[PATCH v1 0/4] ASoc: tac5x1x: mixer-test report

mixer-test report: TAP version 13 # Card 0/titac5x1xsoundc - ti,tac5x1x-soundcard (ti,tac5x1x-soundcard) 1..679 ok 1 get_value.titac5x1xsoundc.96 # titac5x1xsoundc.96 ASI_TX_CH4_EN Capture Switch ok 2 name.titac5x1xsoundc.96 ok 3 write_default.titac5x1xsoundc.96 ok 4 write_valid.titac5x1xsoundc.96 ok 5 write_invalid.titac5x1xsoundc.96 ok 6 event_missing.titac5x1xsoundc.96 ok 7 event_spurious.titac5x1xsoundc.96 ok 8 get_value.titac5x1xsoundc.95 # titac5x1xsoundc.95 ASI_TX_CH3_EN Capture Switch ok 9 name.titac5x1xsoundc.95 ok 10 write_default.titac5x1xsoundc.95 ok 11 write_valid.titac5x1xsoundc.95 ok 12 write_invalid.titac5x1xsoundc.95 ok 13 event_missing.titac5x1xsoundc.95 ok 14 event_spurious.titac5x1xsoundc.95 ok 15 get_value.titac5x1xsoundc.94 # titac5x1xsoundc.94 PDM ch3 & ch4 Datain Select ok 16 name.titac5x1xsoundc.94 ok 17 write_default.titac5x1xsoundc.94 ok 18 write_valid.titac5x1xsoundc.94 ok 19 write_invalid.titac5x1xsoundc.94 ok 20 event_missing.titac5x1xsoundc.94 ok 21 event_spurious.titac5x1xsoundc.94 ok 22 get_value.titac5x1xsoundc.93 # titac5x1xsoundc.93 PDM ch1 & ch2 Datain Select ok 23 name.titac5x1xsoundc.93 ok 24 write_default.titac5x1xsoundc.93 ok 25 write_valid.titac5x1xsoundc.93 ok 26 write_invalid.titac5x1xsoundc.93 ok 27 event_missing.titac5x1xsoundc.93 ok 28 event_spurious.titac5x1xsoundc.93 ok 29 get_value.titac5x1xsoundc.92 # titac5x1xsoundc.92 IN2 Source Mux ok 30 name.titac5x1xsoundc.92 ok 31 write_default.titac5x1xsoundc.92 ok 32 write_valid.titac5x1xsoundc.92 ok 33 write_invalid.titac5x1xsoundc.92 ok 34 event_missing.titac5x1xsoundc.92 ok 35 event_spurious.titac5x1xsoundc.92 ok 36 get_value.titac5x1xsoundc.91 # titac5x1xsoundc.91 IN1 Source Mux ok 37 name.titac5x1xsoundc.91 ok 38 write_default.titac5x1xsoundc.91 ok 39 write_valid.titac5x1xsoundc.91 ok 40 write_invalid.titac5x1xsoundc.91 ok 41 event_missing.titac5x1xsoundc.91 ok 42 event_spurious.titac5x1xsoundc.91 ok 43 get_value.titac5x1xsoundc.90 # titac5x1xsoundc.90 ADC2 Config ok 44 name.titac5x1xsoundc.90 ok 45 write_default.titac5x1xsoundc.90 ok 46 write_valid.titac5x1xsoundc.90 ok 47 write_invalid.titac5x1xsoundc.90 ok 48 event_missing.titac5x1xsoundc.90 ok 49 event_spurious.titac5x1xsoundc.90 ok 50 get_value.titac5x1xsoundc.89 # titac5x1xsoundc.89 ADC2 Full-Scale ok 51 name.titac5x1xsoundc.89 ok 52 write_default.titac5x1xsoundc.89 ok 53 write_valid.titac5x1xsoundc.89 ok 54 write_invalid.titac5x1xsoundc.89 ok 55 event_missing.titac5x1xsoundc.89 ok 56 event_spurious.titac5x1xsoundc.89 ok 57 get_value.titac5x1xsoundc.88 # titac5x1xsoundc.88 ASI_RX_CH2_EN Switch ok 58 name.titac5x1xsoundc.88 ok 59 write_default.titac5x1xsoundc.88 ok 60 write_valid.titac5x1xsoundc.88 ok 61 write_invalid.titac5x1xsoundc.88 ok 62 event_missing.titac5x1xsoundc.88 ok 63 event_spurious.titac5x1xsoundc.88 ok 64 get_value.titac5x1xsoundc.87 # titac5x1xsoundc.87 OUT2x Driver ok 65 name.titac5x1xsoundc.87 ok 66 write_default.titac5x1xsoundc.87 ok 67 write_valid.titac5x1xsoundc.87 ok 68 write_invalid.titac5x1xsoundc.87 ok 69 event_missing.titac5x1xsoundc.87 ok 70 event_spurious.titac5x1xsoundc.87 ok 71 get_value.titac5x1xsoundc.86 # titac5x1xsoundc.86 OUT2x Config ok 72 name.titac5x1xsoundc.86 ok 73 write_default.titac5x1xsoundc.86 ok 74 write_valid.titac5x1xsoundc.86 ok 75 write_invalid.titac5x1xsoundc.86 ok 76 event_missing.titac5x1xsoundc.86 ok 77 event_spurious.titac5x1xsoundc.86 ok 78 get_value.titac5x1xsoundc.85 # titac5x1xsoundc.85 OUT2x Source ok 79 name.titac5x1xsoundc.85 ok 80 write_default.titac5x1xsoundc.85 ok 81 write_valid.titac5x1xsoundc.85 ok 82 write_invalid.titac5x1xsoundc.85 ok 83 event_missing.titac5x1xsoundc.85 ok 84 event_spurious.titac5x1xsoundc.85 ok 85 get_value.titac5x1xsoundc.84 # titac5x1xsoundc.84 ASI_RX_CH1_EN Switch ok 86 name.titac5x1xsoundc.84 ok 87 write_default.titac5x1xsoundc.84 ok 88 write_valid.titac5x1xsoundc.84 ok 89 write_invalid.titac5x1xsoundc.84 ok 90 event_missing.titac5x1xsoundc.84 ok 91 event_spurious.titac5x1xsoundc.84 ok 92 get_value.titac5x1xsoundc.83 # titac5x1xsoundc.83 OUT1x Driver ok 93 name.titac5x1xsoundc.83 ok 94 write_default.titac5x1xsoundc.83 ok 95 write_valid.titac5x1xsoundc.83 ok 96 write_invalid.titac5x1xsoundc.83 ok 97 event_missing.titac5x1xsoundc.83 ok 98 event_spurious.titac5x1xsoundc.83 ok 99 get_value.titac5x1xsoundc.82 # titac5x1xsoundc.82 OUT1x Config ok 100 name.titac5x1xsoundc.82 ok 101 write_default.titac5x1xsoundc.82 ok 102 write_valid.titac5x1xsoundc.82 ok 103 write_invalid.titac5x1xsoundc.82 ok 104 event_missing.titac5x1xsoundc.82 ok 105 event_spurious.titac5x1xsoundc.82 ok 106 get_value.titac5x1xsoundc.81 # titac5x1xsoundc.81 OUT1x Source ok 107 name.titac5x1xsoundc.81 ok 108 write_default.titac5x1xsoundc.81 ok 109 write_valid.titac5x1xsoundc.81 ok 110 write_invalid.titac5x1xsoundc.81 ok 111 event_missing.titac5x1xsoundc.81 ok 112 event_spurious.titac5x1xsoundc.81 ok 113 get_value.titac5x1xsoundc.80 # titac5x1xsoundc.80 ASI_TX_CH2_EN Capture Switch ok 114 name.titac5x1xsoundc.80 ok 115 write_default.titac5x1xsoundc.80 ok 116 write_valid.titac5x1xsoundc.80 ok 117 write_invalid.titac5x1xsoundc.80 ok 118 event_missing.titac5x1xsoundc.80 ok 119 event_spurious.titac5x1xsoundc.80 ok 120 get_value.titac5x1xsoundc.79 # titac5x1xsoundc.79 ASI_TX_CH1_EN Capture Switch ok 121 name.titac5x1xsoundc.79 ok 122 write_default.titac5x1xsoundc.79 ok 123 write_valid.titac5x1xsoundc.79 ok 124 write_invalid.titac5x1xsoundc.79 ok 125 event_missing.titac5x1xsoundc.79 ok 126 event_spurious.titac5x1xsoundc.79 ok 127 get_value.titac5x1xsoundc.78 # titac5x1xsoundc.78 ADC1 Config ok 128 name.titac5x1xsoundc.78 ok 129 write_default.titac5x1xsoundc.78 ok 130 write_valid.titac5x1xsoundc.78 ok 131 write_invalid.titac5x1xsoundc.78 ok 132 event_missing.titac5x1xsoundc.78 ok 133 event_spurious.titac5x1xsoundc.78 ok 134 get_value.titac5x1xsoundc.77 # titac5x1xsoundc.77 ADC1 Full-Scale ok 135 name.titac5x1xsoundc.77 ok 136 write_default.titac5x1xsoundc.77 ok 137 write_valid.titac5x1xsoundc.77 ok 138 write_invalid.titac5x1xsoundc.77 ok 139 event_missing.titac5x1xsoundc.77 ok 140 event_spurious.titac5x1xsoundc.77 ok 141 get_value.titac5x1xsoundc.76 # titac5x1xsoundc.76 IN_CH4_EN Capture Switch ok 142 name.titac5x1xsoundc.76 ok 143 write_default.titac5x1xsoundc.76 ok 144 write_valid.titac5x1xsoundc.76 ok 145 write_invalid.titac5x1xsoundc.76 ok 146 event_missing.titac5x1xsoundc.76 ok 147 event_spurious.titac5x1xsoundc.76 ok 148 get_value.titac5x1xsoundc.75 # titac5x1xsoundc.75 IN_CH3_EN Capture Switch ok 149 name.titac5x1xsoundc.75 ok 150 write_default.titac5x1xsoundc.75 ok 151 write_valid.titac5x1xsoundc.75 ok 152 write_invalid.titac5x1xsoundc.75 ok 153 event_missing.titac5x1xsoundc.75 ok 154 event_spurious.titac5x1xsoundc.75 ok 155 get_value.titac5x1xsoundc.74 # titac5x1xsoundc.74 IN_CH2_EN Capture Switch ok 156 name.titac5x1xsoundc.74 ok 157 write_default.titac5x1xsoundc.74 ok 158 write_valid.titac5x1xsoundc.74 ok 159 write_invalid.titac5x1xsoundc.74 ok 160 event_missing.titac5x1xsoundc.74 ok 161 event_spurious.titac5x1xsoundc.74 ok 162 get_value.titac5x1xsoundc.73 # titac5x1xsoundc.73 IN_CH1_EN Capture Switch ok 163 name.titac5x1xsoundc.73 ok 164 write_default.titac5x1xsoundc.73 ok 165 write_valid.titac5x1xsoundc.73 ok 166 write_invalid.titac5x1xsoundc.73 ok 167 event_missing.titac5x1xsoundc.73 ok 168 event_spurious.titac5x1xsoundc.73 ok 169 get_value.titac5x1xsoundc.72 # titac5x1xsoundc.72 ASI_TX_CH8_SLOT ok 170 name.titac5x1xsoundc.72 ok 171 write_default.titac5x1xsoundc.72 ok 172 write_valid.titac5x1xsoundc.72 ok 173 write_invalid.titac5x1xsoundc.72 ok 174 event_missing.titac5x1xsoundc.72 ok 175 event_spurious.titac5x1xsoundc.72 ok 176 get_value.titac5x1xsoundc.71 # titac5x1xsoundc.71 ASI_TX_CH7_SLOT ok 177 name.titac5x1xsoundc.71 ok 178 write_default.titac5x1xsoundc.71 ok 179 write_valid.titac5x1xsoundc.71 ok 180 write_invalid.titac5x1xsoundc.71 ok 181 event_missing.titac5x1xsoundc.71 ok 182 event_spurious.titac5x1xsoundc.71 ok 183 get_value.titac5x1xsoundc.70 # titac5x1xsoundc.70 ASI_TX_CH6_SLOT ok 184 name.titac5x1xsoundc.70 ok 185 write_default.titac5x1xsoundc.70 ok 186 write_valid.titac5x1xsoundc.70 ok 187 write_invalid.titac5x1xsoundc.70 ok 188 event_missing.titac5x1xsoundc.70 ok 189 event_spurious.titac5x1xsoundc.70 ok 190 get_value.titac5x1xsoundc.69 # titac5x1xsoundc.69 ASI_TX_CH5_SLOT ok 191 name.titac5x1xsoundc.69 ok 192 write_default.titac5x1xsoundc.69 ok 193 write_valid.titac5x1xsoundc.69 ok 194 write_invalid.titac5x1xsoundc.69 ok 195 event_missing.titac5x1xsoundc.69 ok 196 event_spurious.titac5x1xsoundc.69 ok 197 get_value.titac5x1xsoundc.68 # titac5x1xsoundc.68 ASI_TX_CH4_SLOT ok 198 name.titac5x1xsoundc.68 ok 199 write_default.titac5x1xsoundc.68 ok 200 write_valid.titac5x1xsoundc.68 ok 201 write_invalid.titac5x1xsoundc.68 ok 202 event_missing.titac5x1xsoundc.68 ok 203 event_spurious.titac5x1xsoundc.68 ok 204 get_value.titac5x1xsoundc.67 # titac5x1xsoundc.67 ASI_TX_CH3_SLOT ok 205 name.titac5x1xsoundc.67 ok 206 write_default.titac5x1xsoundc.67 ok 207 write_valid.titac5x1xsoundc.67 ok 208 write_invalid.titac5x1xsoundc.67 ok 209 event_missing.titac5x1xsoundc.67 ok 210 event_spurious.titac5x1xsoundc.67 ok 211 get_value.titac5x1xsoundc.66 # titac5x1xsoundc.66 ASI_TX_CH2_SLOT ok 212 name.titac5x1xsoundc.66 ok 213 write_default.titac5x1xsoundc.66 ok 214 write_valid.titac5x1xsoundc.66 ok 215 write_invalid.titac5x1xsoundc.66 ok 216 event_missing.titac5x1xsoundc.66 ok 217 event_spurious.titac5x1xsoundc.66 ok 218 get_value.titac5x1xsoundc.65 # titac5x1xsoundc.65 ASI_TX_CH1_SLOT ok 219 name.titac5x1xsoundc.65 ok 220 write_default.titac5x1xsoundc.65 ok 221 write_valid.titac5x1xsoundc.65 ok 222 write_invalid.titac5x1xsoundc.65 ok 223 event_missing.titac5x1xsoundc.65 ok 224 event_spurious.titac5x1xsoundc.65 ok 225 get_value.titac5x1xsoundc.64 # titac5x1xsoundc.64 ASI_TX_CH8_CFG ok 226 name.titac5x1xsoundc.64 ok 227 write_default.titac5x1xsoundc.64 ok 228 write_valid.titac5x1xsoundc.64 ok 229 write_invalid.titac5x1xsoundc.64 ok 230 event_missing.titac5x1xsoundc.64 ok 231 event_spurious.titac5x1xsoundc.64 ok 232 get_value.titac5x1xsoundc.63 # titac5x1xsoundc.63 ASI_TX_CH7_CFG ok 233 name.titac5x1xsoundc.63 ok 234 write_default.titac5x1xsoundc.63 ok 235 write_valid.titac5x1xsoundc.63 ok 236 write_invalid.titac5x1xsoundc.63 ok 237 event_missing.titac5x1xsoundc.63 ok 238 event_spurious.titac5x1xsoundc.63 ok 239 get_value.titac5x1xsoundc.62 # titac5x1xsoundc.62 ASI_TX_CH6_CFG ok 240 name.titac5x1xsoundc.62 ok 241 write_default.titac5x1xsoundc.62 ok 242 write_valid.titac5x1xsoundc.62 ok 243 write_invalid.titac5x1xsoundc.62 ok 244 event_missing.titac5x1xsoundc.62 ok 245 event_spurious.titac5x1xsoundc.62 ok 246 get_value.titac5x1xsoundc.61 # titac5x1xsoundc.61 ASI_TX_CH5_CFG ok 247 name.titac5x1xsoundc.61 ok 248 write_default.titac5x1xsoundc.61 ok 249 write_valid.titac5x1xsoundc.61 ok 250 write_invalid.titac5x1xsoundc.61 ok 251 event_missing.titac5x1xsoundc.61 ok 252 event_spurious.titac5x1xsoundc.61 ok 253 get_value.titac5x1xsoundc.60 # titac5x1xsoundc.60 ADC1 Phase Capture Volume ok 254 name.titac5x1xsoundc.60 ok 255 write_default.titac5x1xsoundc.60 ok 256 write_valid.titac5x1xsoundc.60 ok 257 write_invalid.titac5x1xsoundc.60 ok 258 event_missing.titac5x1xsoundc.60 ok 259 event_spurious.titac5x1xsoundc.60 ok 260 get_value.titac5x1xsoundc.59 # titac5x1xsoundc.59 ADC1 Fine Capture Volume ok 261 name.titac5x1xsoundc.59 ok 262 write_default.titac5x1xsoundc.59 ok 263 write_valid.titac5x1xsoundc.59 ok 264 write_invalid.titac5x1xsoundc.59 ok 265 event_missing.titac5x1xsoundc.59 ok 266 event_spurious.titac5x1xsoundc.59 ok 267 get_value.titac5x1xsoundc.58 # titac5x1xsoundc.58 ADC1 Digital Capture Volume ok 268 name.titac5x1xsoundc.58 ok 269 write_default.titac5x1xsoundc.58 ok 270 write_valid.titac5x1xsoundc.58 ok 271 write_invalid.titac5x1xsoundc.58 ok 272 event_missing.titac5x1xsoundc.58 ok 273 event_spurious.titac5x1xsoundc.58 ok 274 get_value.titac5x1xsoundc.57 # titac5x1xsoundc.57 ADC1 Audio BW ok 275 name.titac5x1xsoundc.57 ok 276 write_default.titac5x1xsoundc.57 ok 277 write_valid.titac5x1xsoundc.57 ok 278 write_invalid.titac5x1xsoundc.57 ok 279 event_missing.titac5x1xsoundc.57 ok 280 event_spurious.titac5x1xsoundc.57 ok 281 get_value.titac5x1xsoundc.56 # titac5x1xsoundc.56 Record Decimation Filter ok 282 name.titac5x1xsoundc.56 ok 283 write_default.titac5x1xsoundc.56 ok 284 write_valid.titac5x1xsoundc.56 ok 285 write_invalid.titac5x1xsoundc.56 ok 286 event_missing.titac5x1xsoundc.56 ok 287 event_spurious.titac5x1xsoundc.56 ok 288 get_value.titac5x1xsoundc.55 # titac5x1xsoundc.55 GPIO2 GPI ok 289 name.titac5x1xsoundc.55 # GPIO2 GPI is not writeable ok 290 # SKIP write_default.titac5x1xsoundc.55 # GPIO2 GPI is not writeable ok 291 # SKIP write_valid.titac5x1xsoundc.55 # GPIO2 GPI is not writeable ok 292 # SKIP write_invalid.titac5x1xsoundc.55 ok 293 event_missing.titac5x1xsoundc.55 ok 294 event_spurious.titac5x1xsoundc.55 ok 295 get_value.titac5x1xsoundc.54 # titac5x1xsoundc.54 PDM4 Phase Capture Volume ok 296 name.titac5x1xsoundc.54 ok 297 write_default.titac5x1xsoundc.54 ok 298 write_valid.titac5x1xsoundc.54 ok 299 write_invalid.titac5x1xsoundc.54 ok 300 event_missing.titac5x1xsoundc.54 ok 301 event_spurious.titac5x1xsoundc.54 ok 302 get_value.titac5x1xsoundc.53 # titac5x1xsoundc.53 PDM3 Phase Capture Volume ok 303 name.titac5x1xsoundc.53 ok 304 write_default.titac5x1xsoundc.53 ok 305 write_valid.titac5x1xsoundc.53 ok 306 write_invalid.titac5x1xsoundc.53 ok 307 event_missing.titac5x1xsoundc.53 ok 308 event_spurious.titac5x1xsoundc.53 ok 309 get_value.titac5x1xsoundc.52 # titac5x1xsoundc.52 PDM4 Fine Capture Volume ok 310 name.titac5x1xsoundc.52 ok 311 write_default.titac5x1xsoundc.52 ok 312 write_valid.titac5x1xsoundc.52 ok 313 write_invalid.titac5x1xsoundc.52 ok 314 event_missing.titac5x1xsoundc.52 ok 315 event_spurious.titac5x1xsoundc.52 ok 316 get_value.titac5x1xsoundc.51 # titac5x1xsoundc.51 PDM3 Fine Capture Volume ok 317 name.titac5x1xsoundc.51 ok 318 write_default.titac5x1xsoundc.51 ok 319 write_valid.titac5x1xsoundc.51 ok 320 write_invalid.titac5x1xsoundc.51 ok 321 event_missing.titac5x1xsoundc.51 ok 322 event_spurious.titac5x1xsoundc.51 ok 323 get_value.titac5x1xsoundc.50 # titac5x1xsoundc.50 PDM4 Digital Capture Volume ok 324 name.titac5x1xsoundc.50 ok 325 write_default.titac5x1xsoundc.50 ok 326 write_valid.titac5x1xsoundc.50 ok 327 write_invalid.titac5x1xsoundc.50 ok 328 event_missing.titac5x1xsoundc.50 ok 329 event_spurious.titac5x1xsoundc.50 ok 330 get_value.titac5x1xsoundc.49 # titac5x1xsoundc.49 PDM3 Digital Capture Volume ok 331 name.titac5x1xsoundc.49 ok 332 write_default.titac5x1xsoundc.49 ok 333 write_valid.titac5x1xsoundc.49 ok 334 write_invalid.titac5x1xsoundc.49 ok 335 event_missing.titac5x1xsoundc.49 ok 336 event_spurious.titac5x1xsoundc.49 ok 337 get_value.titac5x1xsoundc.48 # titac5x1xsoundc.48 PDM2 Phase Capture Volume ok 338 name.titac5x1xsoundc.48 ok 339 write_default.titac5x1xsoundc.48 ok 340 write_valid.titac5x1xsoundc.48 ok 341 write_invalid.titac5x1xsoundc.48 ok 342 event_missing.titac5x1xsoundc.48 ok 343 event_spurious.titac5x1xsoundc.48 ok 344 get_value.titac5x1xsoundc.47 # titac5x1xsoundc.47 PDM1 Phase Capture Volume ok 345 name.titac5x1xsoundc.47 ok 346 write_default.titac5x1xsoundc.47 ok 347 write_valid.titac5x1xsoundc.47 ok 348 write_invalid.titac5x1xsoundc.47 ok 349 event_missing.titac5x1xsoundc.47 ok 350 event_spurious.titac5x1xsoundc.47 ok 351 get_value.titac5x1xsoundc.46 # titac5x1xsoundc.46 PDM2 Fine Capture Volume ok 352 name.titac5x1xsoundc.46 ok 353 write_default.titac5x1xsoundc.46 ok 354 write_valid.titac5x1xsoundc.46 ok 355 write_invalid.titac5x1xsoundc.46 ok 356 event_missing.titac5x1xsoundc.46 ok 357 event_spurious.titac5x1xsoundc.46 ok 358 get_value.titac5x1xsoundc.45 # titac5x1xsoundc.45 PDM1 Fine Capture Volume ok 359 name.titac5x1xsoundc.45 ok 360 write_default.titac5x1xsoundc.45 ok 361 write_valid.titac5x1xsoundc.45 ok 362 write_invalid.titac5x1xsoundc.45 ok 363 event_missing.titac5x1xsoundc.45 ok 364 event_spurious.titac5x1xsoundc.45 ok 365 get_value.titac5x1xsoundc.44 # titac5x1xsoundc.44 PDM2 Digital Capture Volume ok 366 name.titac5x1xsoundc.44 ok 367 write_default.titac5x1xsoundc.44 ok 368 write_valid.titac5x1xsoundc.44 ok 369 write_invalid.titac5x1xsoundc.44 ok 370 event_missing.titac5x1xsoundc.44 ok 371 event_spurious.titac5x1xsoundc.44 ok 372 get_value.titac5x1xsoundc.43 # titac5x1xsoundc.43 PDM1 Digital Capture Volume ok 373 name.titac5x1xsoundc.43 ok 374 write_default.titac5x1xsoundc.43 ok 375 write_valid.titac5x1xsoundc.43 ok 376 write_invalid.titac5x1xsoundc.43 ok 377 event_missing.titac5x1xsoundc.43 ok 378 event_spurious.titac5x1xsoundc.43 ok 379 get_value.titac5x1xsoundc.42 # titac5x1xsoundc.42 PDM Clk Divider ok 380 name.titac5x1xsoundc.42 ok 381 write_default.titac5x1xsoundc.42 ok 382 write_valid.titac5x1xsoundc.42 ok 383 write_invalid.titac5x1xsoundc.42 ok 384 event_missing.titac5x1xsoundc.42 ok 385 event_spurious.titac5x1xsoundc.42 ok 386 get_value.titac5x1xsoundc.41 # titac5x1xsoundc.41 OUT2X_VCOM ok 387 name.titac5x1xsoundc.41 ok 388 write_default.titac5x1xsoundc.41 ok 389 write_valid.titac5x1xsoundc.41 ok 390 write_invalid.titac5x1xsoundc.41 ok 391 event_missing.titac5x1xsoundc.41 ok 392 event_spurious.titac5x1xsoundc.41 ok 393 get_value.titac5x1xsoundc.40 # titac5x1xsoundc.40 DAC2 Audio BW ok 394 name.titac5x1xsoundc.40 ok 395 write_default.titac5x1xsoundc.40 ok 396 write_valid.titac5x1xsoundc.40 ok 397 write_invalid.titac5x1xsoundc.40 ok 398 event_missing.titac5x1xsoundc.40 ok 399 event_spurious.titac5x1xsoundc.40 ok 400 get_value.titac5x1xsoundc.39 # titac5x1xsoundc.39 DAC2 CHB Gain Calibration Playback Volume ok 401 name.titac5x1xsoundc.39 ok 402 write_default.titac5x1xsoundc.39 ok 403 write_valid.titac5x1xsoundc.39 ok 404 write_invalid.titac5x1xsoundc.39 ok 405 event_missing.titac5x1xsoundc.39 ok 406 event_spurious.titac5x1xsoundc.39 ok 407 get_value.titac5x1xsoundc.38 # titac5x1xsoundc.38 DAC2 CHA Gain Calibration Playback Volume ok 408 name.titac5x1xsoundc.38 ok 409 write_default.titac5x1xsoundc.38 ok 410 write_valid.titac5x1xsoundc.38 ok 411 write_invalid.titac5x1xsoundc.38 ok 412 event_missing.titac5x1xsoundc.38 ok 413 event_spurious.titac5x1xsoundc.38 ok 414 get_value.titac5x1xsoundc.37 # titac5x1xsoundc.37 DAC2 CHB Digital Playback Volume ok 415 name.titac5x1xsoundc.37 ok 416 write_default.titac5x1xsoundc.37 ok 417 write_valid.titac5x1xsoundc.37 ok 418 write_invalid.titac5x1xsoundc.37 ok 419 event_missing.titac5x1xsoundc.37 ok 420 event_spurious.titac5x1xsoundc.37 ok 421 get_value.titac5x1xsoundc.36 # titac5x1xsoundc.36 DAC2 CHA Digital Playback Volume ok 422 name.titac5x1xsoundc.36 ok 423 write_default.titac5x1xsoundc.36 ok 424 write_valid.titac5x1xsoundc.36 ok 425 write_invalid.titac5x1xsoundc.36 ok 426 event_missing.titac5x1xsoundc.36 ok 427 event_spurious.titac5x1xsoundc.36 ok 428 get_value.titac5x1xsoundc.35 # titac5x1xsoundc.35 OUT2M Analog Level Playback Volume ok 429 name.titac5x1xsoundc.35 ok 430 write_default.titac5x1xsoundc.35 ok 431 write_valid.titac5x1xsoundc.35 ok 432 write_invalid.titac5x1xsoundc.35 ok 433 event_missing.titac5x1xsoundc.35 ok 434 event_spurious.titac5x1xsoundc.35 ok 435 get_value.titac5x1xsoundc.34 # titac5x1xsoundc.34 OUT2P Analog Level Playback Volume ok 436 name.titac5x1xsoundc.34 ok 437 write_default.titac5x1xsoundc.34 ok 438 write_valid.titac5x1xsoundc.34 ok 439 write_invalid.titac5x1xsoundc.34 ok 440 event_missing.titac5x1xsoundc.34 ok 441 event_spurious.titac5x1xsoundc.34 ok 442 get_value.titac5x1xsoundc.33 # titac5x1xsoundc.33 ADC2 Phase Capture Volume ok 443 name.titac5x1xsoundc.33 ok 444 write_default.titac5x1xsoundc.33 ok 445 write_valid.titac5x1xsoundc.33 ok 446 write_invalid.titac5x1xsoundc.33 ok 447 event_missing.titac5x1xsoundc.33 ok 448 event_spurious.titac5x1xsoundc.33 ok 449 get_value.titac5x1xsoundc.32 # titac5x1xsoundc.32 ADC2 Fine Capture Volume ok 450 name.titac5x1xsoundc.32 ok 451 write_default.titac5x1xsoundc.32 ok 452 write_valid.titac5x1xsoundc.32 ok 453 write_invalid.titac5x1xsoundc.32 ok 454 event_missing.titac5x1xsoundc.32 ok 455 event_spurious.titac5x1xsoundc.32 ok 456 get_value.titac5x1xsoundc.31 # titac5x1xsoundc.31 ADC2 Digital Capture Volume ok 457 name.titac5x1xsoundc.31 ok 458 write_default.titac5x1xsoundc.31 ok 459 write_valid.titac5x1xsoundc.31 ok 460 write_invalid.titac5x1xsoundc.31 ok 461 event_missing.titac5x1xsoundc.31 ok 462 event_spurious.titac5x1xsoundc.31 ok 463 get_value.titac5x1xsoundc.30 # titac5x1xsoundc.30 ADC2 Audio BW ok 464 name.titac5x1xsoundc.30 ok 465 write_default.titac5x1xsoundc.30 ok 466 write_valid.titac5x1xsoundc.30 ok 467 write_invalid.titac5x1xsoundc.30 ok 468 event_missing.titac5x1xsoundc.30 ok 469 event_spurious.titac5x1xsoundc.30 ok 470 get_value.titac5x1xsoundc.29 # titac5x1xsoundc.29 OUT_CH4_EN Playback Switch ok 471 name.titac5x1xsoundc.29 ok 472 write_default.titac5x1xsoundc.29 ok 473 write_valid.titac5x1xsoundc.29 ok 474 write_invalid.titac5x1xsoundc.29 ok 475 event_missing.titac5x1xsoundc.29 ok 476 event_spurious.titac5x1xsoundc.29 ok 477 get_value.titac5x1xsoundc.28 # titac5x1xsoundc.28 OUT_CH3_EN Playback Switch ok 478 name.titac5x1xsoundc.28 ok 479 write_default.titac5x1xsoundc.28 ok 480 write_valid.titac5x1xsoundc.28 ok 481 write_invalid.titac5x1xsoundc.28 ok 482 event_missing.titac5x1xsoundc.28 ok 483 event_spurious.titac5x1xsoundc.28 ok 484 get_value.titac5x1xsoundc.27 # titac5x1xsoundc.27 OUT_CH2_EN Playback Switch ok 485 name.titac5x1xsoundc.27 ok 486 write_default.titac5x1xsoundc.27 ok 487 write_valid.titac5x1xsoundc.27 ok 488 write_invalid.titac5x1xsoundc.27 ok 489 event_missing.titac5x1xsoundc.27 ok 490 event_spurious.titac5x1xsoundc.27 ok 491 get_value.titac5x1xsoundc.26 # titac5x1xsoundc.26 OUT_CH1_EN Playback Switch ok 492 name.titac5x1xsoundc.26 ok 493 write_default.titac5x1xsoundc.26 ok 494 write_valid.titac5x1xsoundc.26 ok 495 write_invalid.titac5x1xsoundc.26 ok 496 event_missing.titac5x1xsoundc.26 ok 497 event_spurious.titac5x1xsoundc.26 ok 498 get_value.titac5x1xsoundc.25 # titac5x1xsoundc.25 ASI_RX_CH8_SLOT Playback ok 499 name.titac5x1xsoundc.25 ok 500 write_default.titac5x1xsoundc.25 ok 501 write_valid.titac5x1xsoundc.25 ok 502 write_invalid.titac5x1xsoundc.25 ok 503 event_missing.titac5x1xsoundc.25 ok 504 event_spurious.titac5x1xsoundc.25 ok 505 get_value.titac5x1xsoundc.24 # titac5x1xsoundc.24 ASI_RX_CH7_SLOT Playback ok 506 name.titac5x1xsoundc.24 ok 507 write_default.titac5x1xsoundc.24 ok 508 write_valid.titac5x1xsoundc.24 ok 509 write_invalid.titac5x1xsoundc.24 ok 510 event_missing.titac5x1xsoundc.24 ok 511 event_spurious.titac5x1xsoundc.24 ok 512 get_value.titac5x1xsoundc.23 # titac5x1xsoundc.23 ASI_RX_CH6_SLOT Playback ok 513 name.titac5x1xsoundc.23 ok 514 write_default.titac5x1xsoundc.23 ok 515 write_valid.titac5x1xsoundc.23 ok 516 write_invalid.titac5x1xsoundc.23 ok 517 event_missing.titac5x1xsoundc.23 ok 518 event_spurious.titac5x1xsoundc.23 ok 519 get_value.titac5x1xsoundc.22 # titac5x1xsoundc.22 ASI_RX_CH5_SLOT Playback ok 520 name.titac5x1xsoundc.22 ok 521 write_default.titac5x1xsoundc.22 ok 522 write_valid.titac5x1xsoundc.22 ok 523 write_invalid.titac5x1xsoundc.22 ok 524 event_missing.titac5x1xsoundc.22 ok 525 event_spurious.titac5x1xsoundc.22 ok 526 get_value.titac5x1xsoundc.21 # titac5x1xsoundc.21 ASI_RX_CH4_SLOT Playback ok 527 name.titac5x1xsoundc.21 ok 528 write_default.titac5x1xsoundc.21 ok 529 write_valid.titac5x1xsoundc.21 ok 530 write_invalid.titac5x1xsoundc.21 ok 531 event_missing.titac5x1xsoundc.21 ok 532 event_spurious.titac5x1xsoundc.21 ok 533 get_value.titac5x1xsoundc.20 # titac5x1xsoundc.20 ASI_RX_CH3_SLOT Playback ok 534 name.titac5x1xsoundc.20 ok 535 write_default.titac5x1xsoundc.20 ok 536 write_valid.titac5x1xsoundc.20 ok 537 write_invalid.titac5x1xsoundc.20 ok 538 event_missing.titac5x1xsoundc.20 ok 539 event_spurious.titac5x1xsoundc.20 ok 540 get_value.titac5x1xsoundc.19 # titac5x1xsoundc.19 ASI_RX_CH2_SLOT Playback ok 541 name.titac5x1xsoundc.19 ok 542 write_default.titac5x1xsoundc.19 ok 543 write_valid.titac5x1xsoundc.19 ok 544 write_invalid.titac5x1xsoundc.19 ok 545 event_missing.titac5x1xsoundc.19 ok 546 event_spurious.titac5x1xsoundc.19 ok 547 get_value.titac5x1xsoundc.18 # titac5x1xsoundc.18 ASI_RX_CH1_SLOT Playback ok 548 name.titac5x1xsoundc.18 ok 549 write_default.titac5x1xsoundc.18 ok 550 write_valid.titac5x1xsoundc.18 ok 551 write_invalid.titac5x1xsoundc.18 ok 552 event_missing.titac5x1xsoundc.18 ok 553 event_spurious.titac5x1xsoundc.18 ok 554 get_value.titac5x1xsoundc.17 # titac5x1xsoundc.17 ASI_RX_CH8_EN Playback ok 555 name.titac5x1xsoundc.17 ok 556 write_default.titac5x1xsoundc.17 ok 557 write_valid.titac5x1xsoundc.17 ok 558 write_invalid.titac5x1xsoundc.17 ok 559 event_missing.titac5x1xsoundc.17 ok 560 event_spurious.titac5x1xsoundc.17 ok 561 get_value.titac5x1xsoundc.16 # titac5x1xsoundc.16 ASI_RX_CH7_EN Playback ok 562 name.titac5x1xsoundc.16 ok 563 write_default.titac5x1xsoundc.16 ok 564 write_valid.titac5x1xsoundc.16 ok 565 write_invalid.titac5x1xsoundc.16 ok 566 event_missing.titac5x1xsoundc.16 ok 567 event_spurious.titac5x1xsoundc.16 ok 568 get_value.titac5x1xsoundc.15 # titac5x1xsoundc.15 ASI_RX_CH6_EN Playback ok 569 name.titac5x1xsoundc.15 ok 570 write_default.titac5x1xsoundc.15 ok 571 write_valid.titac5x1xsoundc.15 ok 572 write_invalid.titac5x1xsoundc.15 ok 573 event_missing.titac5x1xsoundc.15 ok 574 event_spurious.titac5x1xsoundc.15 ok 575 get_value.titac5x1xsoundc.14 # titac5x1xsoundc.14 ASI_RX_CH5_EN Playback ok 576 name.titac5x1xsoundc.14 ok 577 write_default.titac5x1xsoundc.14 ok 578 write_valid.titac5x1xsoundc.14 ok 579 write_invalid.titac5x1xsoundc.14 ok 580 event_missing.titac5x1xsoundc.14 ok 581 event_spurious.titac5x1xsoundc.14 ok 582 get_value.titac5x1xsoundc.13 # titac5x1xsoundc.13 ASI_RX_CH4_EN Playback ok 583 name.titac5x1xsoundc.13 ok 584 write_default.titac5x1xsoundc.13 ok 585 write_valid.titac5x1xsoundc.13 ok 586 write_invalid.titac5x1xsoundc.13 ok 587 event_missing.titac5x1xsoundc.13 ok 588 event_spurious.titac5x1xsoundc.13 ok 589 get_value.titac5x1xsoundc.12 # titac5x1xsoundc.12 ASI_RX_CH3_EN Playback ok 590 name.titac5x1xsoundc.12 ok 591 write_default.titac5x1xsoundc.12 ok 592 write_valid.titac5x1xsoundc.12 ok 593 write_invalid.titac5x1xsoundc.12 ok 594 event_missing.titac5x1xsoundc.12 ok 595 event_spurious.titac5x1xsoundc.12 ok 596 get_value.titac5x1xsoundc.11 # titac5x1xsoundc.11 DAC1 CHB Gain Calibration Playback Volume ok 597 name.titac5x1xsoundc.11 ok 598 write_default.titac5x1xsoundc.11 ok 599 write_valid.titac5x1xsoundc.11 ok 600 write_invalid.titac5x1xsoundc.11 ok 601 event_missing.titac5x1xsoundc.11 ok 602 event_spurious.titac5x1xsoundc.11 ok 603 get_value.titac5x1xsoundc.10 # titac5x1xsoundc.10 DAC1 CHA Gain Calibration Playback Volume ok 604 name.titac5x1xsoundc.10 ok 605 write_default.titac5x1xsoundc.10 ok 606 write_valid.titac5x1xsoundc.10 ok 607 write_invalid.titac5x1xsoundc.10 ok 608 event_missing.titac5x1xsoundc.10 ok 609 event_spurious.titac5x1xsoundc.10 ok 610 get_value.titac5x1xsoundc.9 # titac5x1xsoundc.9 DAC1 CHB Digital Playback Volume ok 611 name.titac5x1xsoundc.9 ok 612 write_default.titac5x1xsoundc.9 ok 613 write_valid.titac5x1xsoundc.9 ok 614 write_invalid.titac5x1xsoundc.9 ok 615 event_missing.titac5x1xsoundc.9 ok 616 event_spurious.titac5x1xsoundc.9 ok 617 get_value.titac5x1xsoundc.8 # titac5x1xsoundc.8 DAC1 CHA Digital Playback Volume ok 618 name.titac5x1xsoundc.8 ok 619 write_default.titac5x1xsoundc.8 ok 620 write_valid.titac5x1xsoundc.8 ok 621 write_invalid.titac5x1xsoundc.8 ok 622 event_missing.titac5x1xsoundc.8 ok 623 event_spurious.titac5x1xsoundc.8 ok 624 get_value.titac5x1xsoundc.7 # titac5x1xsoundc.7 OUT1M Analog Level Playback Volume ok 625 name.titac5x1xsoundc.7 ok 626 write_default.titac5x1xsoundc.7 ok 627 write_valid.titac5x1xsoundc.7 ok 628 write_invalid.titac5x1xsoundc.7 ok 629 event_missing.titac5x1xsoundc.7 ok 630 event_spurious.titac5x1xsoundc.7 ok 631 get_value.titac5x1xsoundc.6 # titac5x1xsoundc.6 OUT1P Analog Level Playback Volume ok 632 name.titac5x1xsoundc.6 ok 633 write_default.titac5x1xsoundc.6 ok 634 write_valid.titac5x1xsoundc.6 ok 635 write_invalid.titac5x1xsoundc.6 ok 636 event_missing.titac5x1xsoundc.6 ok 637 event_spurious.titac5x1xsoundc.6 ok 638 get_value.titac5x1xsoundc.5 # titac5x1xsoundc.5 DAC1 Audio BW ok 639 name.titac5x1xsoundc.5 ok 640 write_default.titac5x1xsoundc.5 ok 641 write_valid.titac5x1xsoundc.5 ok 642 write_invalid.titac5x1xsoundc.5 ok 643 event_missing.titac5x1xsoundc.5 ok 644 event_spurious.titac5x1xsoundc.5 ok 645 get_value.titac5x1xsoundc.4 # titac5x1xsoundc.4 Playback Decimation Filter ok 646 name.titac5x1xsoundc.4 ok 647 write_default.titac5x1xsoundc.4 ok 648 write_valid.titac5x1xsoundc.4 ok 649 write_invalid.titac5x1xsoundc.4 ok 650 event_missing.titac5x1xsoundc.4 ok 651 event_spurious.titac5x1xsoundc.4 ok 652 get_value.titac5x1xsoundc.3 # titac5x1xsoundc.3 ADC2 Common-mode Tolerance ok 653 name.titac5x1xsoundc.3 ok 654 write_default.titac5x1xsoundc.3 ok 655 write_valid.titac5x1xsoundc.3 ok 656 write_invalid.titac5x1xsoundc.3 ok 657 event_missing.titac5x1xsoundc.3 ok 658 event_spurious.titac5x1xsoundc.3 ok 659 get_value.titac5x1xsoundc.2 # titac5x1xsoundc.2 ADC1 Common-mode Tolerance ok 660 name.titac5x1xsoundc.2 ok 661 write_default.titac5x1xsoundc.2 ok 662 write_valid.titac5x1xsoundc.2 ok 663 write_invalid.titac5x1xsoundc.2 ok 664 event_missing.titac5x1xsoundc.2 ok 665 event_spurious.titac5x1xsoundc.2 ok 666 get_value.titac5x1xsoundc.1 # titac5x1xsoundc.1 ADC2 Impedance Select ok 667 name.titac5x1xsoundc.1 ok 668 write_default.titac5x1xsoundc.1 ok 669 write_valid.titac5x1xsoundc.1 ok 670 write_invalid.titac5x1xsoundc.1 ok 671 event_missing.titac5x1xsoundc.1 ok 672 event_spurious.titac5x1xsoundc.1 ok 673 get_value.titac5x1xsoundc.0 # titac5x1xsoundc.0 ADC1 Impedance Select ok 674 name.titac5x1xsoundc.0 ok 675 write_default.titac5x1xsoundc.0 ok 676 write_valid.titac5x1xsoundc.0 ok 677 write_invalid.titac5x1xsoundc.0 ok 678 event_missing.titac5x1xsoundc.0 ok 679 event_spurious.titac5x1xsoundc.0 # 3 skipped test(s) detected. Consider enabling relevant config options to improve coverage. # Totals: pass:676 fail:0 xfail:0 xpass:0 skip:3 error:0
Signed-off-by: Niranjan H Y niranjan.hy@ti.com
Niranjan H Y (4): ASoc: tac5x1x: add codec driver tac5x1x family Asoc: tac5x1x: document tac5x1x codec Asoc: pcm6240: remove support for taac5x1x family ASoc: pcm6240: dt-bindings device support list update
.../devicetree/bindings/sound/ti,pcm6240.yaml | 10 - .../devicetree/bindings/sound/ti,tac5x1x.yaml | 222 ++ sound/soc/codecs/Kconfig | 16 + sound/soc/codecs/Makefile | 6 +- sound/soc/codecs/pcm6240.c | 124 +- sound/soc/codecs/pcm6240.h | 4 - sound/soc/codecs/tac5x1x-i2c.c | 81 + sound/soc/codecs/tac5x1x.c | 2389 +++++++++++++++++ sound/soc/codecs/tac5x1x.h | 302 +++ 9 files changed, 3018 insertions(+), 136 deletions(-) create mode 100644 Documentation/devicetree/bindings/sound/ti,tac5x1x.yaml create mode 100644 sound/soc/codecs/tac5x1x-i2c.c create mode 100644 sound/soc/codecs/tac5x1x.c create mode 100644 sound/soc/codecs/tac5x1x.h

tac5x1x family are series of low-power and high performance mono/stereo audio codecs consists of ADC and DAC combinations. The patch adds supports for Codecs(DAC & ADC), ADC only and DAC only configurations available in the tac5x1x family.
Signed-off-by: Niranjan H Y niranjan.hy@ti.com --- sound/soc/codecs/Kconfig | 16 + sound/soc/codecs/Makefile | 6 +- sound/soc/codecs/tac5x1x-i2c.c | 81 ++ sound/soc/codecs/tac5x1x.c | 2389 ++++++++++++++++++++++++++++++++ sound/soc/codecs/tac5x1x.h | 302 ++++ 5 files changed, 2793 insertions(+), 1 deletion(-) create mode 100644 sound/soc/codecs/tac5x1x-i2c.c create mode 100644 sound/soc/codecs/tac5x1x.c create mode 100644 sound/soc/codecs/tac5x1x.h
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 477d33234fdd..74abc0d68237 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -258,6 +258,8 @@ config SND_SOC_ALL_CODECS imply SND_SOC_STA529 imply SND_SOC_STAC9766 imply SND_SOC_STI_SAS + imply SND_SOC_TAC5X1X + imply SND_SOC_TAC5X1X_I2C imply SND_SOC_TAS2552 imply SND_SOC_TAS2562 imply SND_SOC_TAS2764 @@ -2001,6 +2003,20 @@ config SND_SOC_STAC9766 config SND_SOC_STI_SAS tristate "codec Audio support for STI SAS codec"
+config SND_SOC_TAC5X1X + tristate "Texas Instruments TAC5X1X family codecs" + depends on I2C && REGMAP_I2C + +config SND_SOC_TAC5X1X_I2C + tristate "Texas Instruments TAC5X1X family driver based on I2C" + depends on I2C && REGMAP_I2C + select SND_SOC_TAC5X1X + help + Enable support for Texas Instruments TAC5X1X family Audio chips. + The family consists mono/stereo audio codecs, DACs and ADCs. + Includes support for TAC5311-Q1, TAC5411-Q1, TAC5111, TAC5211, + TAA5212, TAA5412-Q1, TAD5112, TAD5212, TAC5312, TAC5412-Q1, + config SND_SOC_TAS2552 tristate "Texas Instruments TAS2552 Mono Audio amplifier" depends on I2C diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 66e2f2381d40..ec315236f2d9 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -312,6 +312,8 @@ snd-soc-tas2770-y := tas2770.o snd-soc-tas2781-comlib-y := tas2781-comlib.o snd-soc-tas2781-fmwlib-y := tas2781-fmwlib.o snd-soc-tas2781-i2c-y := tas2781-i2c.o +snd-soc-tac5x1x-y := tac5x1x.o +snd-soc-tac5x1x-i2c-y := tac5x1x-i2c.o snd-soc-tfa9879-y := tfa9879.o snd-soc-tfa989x-y := tfa989x.o snd-soc-tlv320adc3xxx-y := tlv320adc3xxx.o @@ -717,6 +719,8 @@ obj-$(CONFIG_SND_SOC_STA32X) += snd-soc-sta32x.o obj-$(CONFIG_SND_SOC_STA350) += snd-soc-sta350.o obj-$(CONFIG_SND_SOC_STA529) += snd-soc-sta529.o obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o +obj-$(CONFIG_SND_SOC_TAC5X1X) += snd-soc-tac5x1x.o +obj-$(CONFIG_SND_SOC_TAC5X1X_I2C) += snd-soc-tac5x1x-i2c.o obj-$(CONFIG_SND_SOC_STI_SAS) += snd-soc-sti-sas.o obj-$(CONFIG_SND_SOC_TAS2552) += snd-soc-tas2552.o obj-$(CONFIG_SND_SOC_TAS2562) += snd-soc-tas2562.o @@ -851,4 +855,4 @@ obj-$(CONFIG_SND_SOC_LPASS_RX_MACRO) += snd-soc-lpass-rx-macro.o obj-$(CONFIG_SND_SOC_LPASS_TX_MACRO) += snd-soc-lpass-tx-macro.o
# Mux -obj-$(CONFIG_SND_SOC_SIMPLE_MUX) += snd-soc-simple-mux.o \ No newline at end of file +obj-$(CONFIG_SND_SOC_SIMPLE_MUX) += snd-soc-simple-mux.o diff --git a/sound/soc/codecs/tac5x1x-i2c.c b/sound/soc/codecs/tac5x1x-i2c.c new file mode 100644 index 000000000000..26af55a29b03 --- /dev/null +++ b/sound/soc/codecs/tac5x1x-i2c.c @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// ALSA SoC Texas Instruments TAC5x1x Audio Codec +// +// Copyright (C) 2020 - 2025 Texas Instruments Incorporated +// https://www.ti.com +// +// TAC5x1x are a series of low-power and high performance mono or stereo +// audio codecs, as well as multiple inputs and outputs programmable in +// single-ended or fully differential configurations. Device supports both +// Microphone and Line In input on ADC Channel. DAC Output can be configured +// for either Line Out or Head Phone Load. +// +// Author: Kevin Lu kevin-lu@ti.com +// Author: Kokila Karuppusamy kokila.karuppusamy@ti.com +// Author: Niranjan H Y niranjan.hy@ti.com +// + +#include <linux/i2c.h> +#include <linux/regmap.h> +#include <linux/module.h> + +#include "tac5x1x.h" + +static const struct i2c_device_id tac5x1x_id[] = { + { "taa5212", TAA5212 }, + { "taa5412", TAA5412 }, + { "tac5111", TAC5111 }, + { "tac5112", TAC5112 }, + { "tac5211", TAC5211 }, + { "tac5212", TAC5212 }, + { "tac5311", TAC5311 }, + { "tac5312", TAC5312 }, + { "tac5411", TAC5411 }, + { "tac5412", TAC5412 }, + { "tad5112", TAD5112 }, + { "tad5212", TAD5212 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, tac5x1x_id); + +static int tac5x1x_i2c_probe(struct i2c_client *i2c) +{ + int ret; + enum tac5x1x_type type; + struct regmap *regmap; + const struct regmap_config *config = &tac5x1x_regmap; + + regmap = devm_regmap_init_i2c(i2c, config); + type = (uintptr_t)i2c_get_match_data(i2c); + + dev_info(&i2c->dev, "probing %s codec_type = %d\n", + i2c->name, type); + + ret = tac5x1x_probe(&i2c->dev, regmap, type); + if (ret) + dev_err(&i2c->dev, "probe failed"); + + return ret; +} + +static void tac5x1x_i2c_remove(struct i2c_client *client) +{ + tac5x1x_remove(&client->dev); +} + +static struct i2c_driver tac5x1x_i2c_driver = { + .driver = { + .name = "tac5x1x-codec", + .of_match_table = of_match_ptr(tac5x1x_of_match), + }, + .probe = tac5x1x_i2c_probe, + .remove = tac5x1x_i2c_remove, + .id_table = tac5x1x_id, +}; + +module_i2c_driver(tac5x1x_i2c_driver); + +MODULE_DESCRIPTION("ASoC tac5x1x codec driver"); +MODULE_AUTHOR("Texas Instruments"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/tac5x1x.c b/sound/soc/codecs/tac5x1x.c new file mode 100644 index 000000000000..f0481a2aebd0 --- /dev/null +++ b/sound/soc/codecs/tac5x1x.c @@ -0,0 +1,2389 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// tac5x1x.c +// +// Copyright (C) 2022 - 2025 Texas Instruments Incorporated +// +// Author: Kevin Lu kevin-lu@ti.com +// Author: Kokila Karuppusamy kokila.karuppusamy@ti.com +// Author: Niranjan H Y niranjan.hy@ti.com +// + +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_gpio.h> +#include <linux/of_irq.h> +#include <linux/regulator/consumer.h> +#include <sound/pcm_params.h> +#include <sound/soc.h> +#include <linux/regmap.h> +#include <linux/device.h> +#include <sound/tlv.h> + +#include "tac5x1x.h" + +struct tac5x1x_setup_gpio { + s32 gpio_func[3]; + s32 gpio_drive[3]; + s32 gpi1_func; + s32 gpa_gpio; +}; + +struct tac5x1x_input_diag_config { + s32 in_ch_en; + s32 out_ch_en; + s32 incl_se_inm; + s32 incl_ac_coup; +}; + +struct tac5x1x_irqinfo { + struct delayed_work irq_work; + s32 irq_gpio; + s32 irq; + bool irq_enable; +}; + +struct tac5x1x_dev { + u32 addr; + bool is_loading; +}; + +struct interrupt_info { + const char * const *names; + size_t size; +}; + +struct tac5x1x_priv { + struct snd_soc_component *component; + struct regmap *regmap; + struct device *dev; + enum tac5x1x_type codec_type; + bool pll_setup; + s32 irq; + s32 vref_vg; + s32 adc_en; + s32 dac_en; + s32 micbias_en; + s32 micbias_vg; + s32 agc_en; + s32 uad_en; + s32 vad_en; + s32 uag_en; + s32 dac_mute; + s32 dac_dig_vol[4]; + s32 dac_chns; + u32 sysclk; + s32 ndev; + s32 micbias_threshold[2]; + s32 gpa_threshold[2]; + u8 dev_name[20]; + struct snd_soc_jack *jack; + struct regulator *supply_avdd; + struct regulator *supply_iovdd; + struct tac5x1x_setup_gpio *gpio_setup; + struct tac5x1x_irqinfo irqinfo; + /* mutex to prevent simulataneous device read */ + struct mutex dev_lock; + struct tac5x1x_dev tac5x1x_dev[2]; + struct tac5x1x_input_diag_config input_diag_config; + void (*irq_work_func)(struct tac5x1x_priv *tac5x1x); +}; + +static const char * const int_ltch0[] = { + "Clock Error", + "PLL Lock", + "Boost Over Temperature", + "Boost Over Current", + "Boost Mode", + "Reserved", + "Reserved", + "Reserved", +}; + +static const char * const chx_ltch[] = { + "Input Channel1 fault", + "Input Channel2 fault", + "Output Channel1 fault", + "Output Channel2 fault", + "Short to VBAT_IN", + "Reserved", + "Reserved", + "Reserved", +}; + +static const char * const in_ch1_ltch[] = { + "IN_CH1 open Input", + "IN_CH1 Input shorted", + "IN_CH1 INP shorted to GND", + "IN_CH1 INM shorted to GND", + "IN_CH1 INP shorted to MICBIAS", + "IN_CH1 INM shorted to MICBIAS", + "IN_CH1 INP shorted to VBAT_IN", + "IN_CH1 INM shorted to VBAT_IN", +}; + +static const char * const in_ch2_ltch[] = { + "IN_CH2 open Input", + "IN_CH2 Input shorted", + "IN_CH2 INP shorted to GND", + "IN_CH2 INM shorted to GND", + "IN_CH2 INP shorted to MICBIAS", + "IN_CH2 INM shorted to MICBIAS", + "IN_CH2 INP shorted to VBAT_IN", + "IN_CH2 INM shorted to VBAT_IN", +}; + +static const char * const out_ch1_ltch[] = { + "OUT_CH1 OUT1P Short circuit Fault", + "OUT_CH1 OUT1M Short circuit Fault", + "OUT_CH1 DRVRP Virtual Ground Fault", + "OUT_CH1 DRVRM Virtual ground Fault", + "OUT_CH1 ADC CH1 Mask", + "OUT_CH1 ADC CH2 MASK", + "Reserved", + "Reserved", +}; + +static const char * const out_ch2_ltch[] = { + "OUT_CH2 OUT2P Short circuit Fault", + "OUT_CH2 OUT2M Short circuit Fault", + "OUT_CH2 DRVRP Virtual Ground Fault", + "OUT_CH2 DRVRM Virtual ground Fault", + "Reserved", + "Reserved", + "AREG SC Fault Mask", + "AREG SC Fault", +}; + +static const char * const int_ltch1[] = { + "CH1 INP Over Voltage", + "CH1 INM Over Voltage", + "CH2 INP over Voltage", + "CH2 INM Over Voltage", + "Headset Insert Detection", + "Headset Remove Detection", + "Headset Hook", + "MIPS Overload", +}; + +static const char * const int_ltch2[] = { + "GPA Up threashold Fault", + "GPA low threashold Fault", + "VAD Power up detect", + "VAD power down detect", + "Micbias short circuit", + "Micbias high current fault", + "Micbias low current fault", + "Micbias Over voltage fault", +}; + +static u32 int_reg_array[] = { + TAC5X1X_REG_INT_LTCH0, + TAC5X1X_REG_CHX_LTCH, + TAC5X1X_REG_IN_CH1_LTCH, + TAC5X1X_REG_IN_CH2_LTCH, + TAC5X1X_REG_OUT_CH1_LTCH, + TAC5X1X_REG_OUT_CH2_LTCH, + TAC5X1X_REG_INT_LTCH1, + TAC5X1X_REG_INT_LTCH2, +}; + +static const char * const int_reg_arr_name[] = { + "TAC5X1X_REG_INT_LTCH0", + "TAC5X1X_REG_CHX_LTCH", + "TAC5X1X_REG_IN_CH1_LTCH", + "TAC5X1X_REG_IN_CH2_LTCH", + "TAC5X1X_REG_OUT_CH1_LTCH", + "TAC5X1X_REG_OUT_CH2_LTCH", + "TAC5X1X_REG_INT_LTCH1", + "TAC5X1X_REG_INT_LTCH2", +}; + +static const struct interrupt_info interrupts[] = { + { int_ltch0, ARRAY_SIZE(int_ltch0) }, + { chx_ltch, ARRAY_SIZE(chx_ltch) }, + { in_ch1_ltch, ARRAY_SIZE(in_ch1_ltch) }, + { in_ch2_ltch, ARRAY_SIZE(in_ch2_ltch) }, + { out_ch1_ltch, ARRAY_SIZE(out_ch1_ltch) }, + { out_ch2_ltch, ARRAY_SIZE(out_ch2_ltch) }, + { int_ltch1, ARRAY_SIZE(int_ltch1) }, + { int_ltch2, ARRAY_SIZE(int_ltch2) }, +}; + +static s32 tac5x1x_regmap_write(struct tac5x1x_priv *tac5x1x, + u32 reg, u32 value) +{ + s32 ret; + s32 retry_count = 5; + + while (retry_count--) { + ret = regmap_write(tac5x1x->regmap, reg, + value); + if (ret >= 0) + break; + usleep_range(5000, 5050); + } + if (retry_count == -1) + return 3; + else + return ret; +} + +static s32 tac5x1x_regmap_read(struct tac5x1x_priv *tac5x1x, + u32 reg, u32 *value) +{ + s32 ret; + s32 retry_count = 5; + + ret = regmap_reinit_cache(tac5x1x->regmap, &tac5x1x_regmap); + if (ret) { + dev_err(tac5x1x->dev, "Failed to reinit reg cache\n"); + return ret; + } + + while (retry_count--) { + ret = regmap_read(tac5x1x->regmap, reg, + value); + if (ret >= 0) + break; + usleep_range(5000, 5050); + } + if (retry_count == -1) + return 3; + else + return ret; +} + +static s32 tac5x1x_dev_read(struct tac5x1x_priv *tac5x1x, + u32 dev_no, u32 reg, + u32 *ref_value) +{ + s32 ret; + + guard(mutex)(&tac5x1x->dev_lock); + if (dev_no < tac5x1x->ndev) { + ret = tac5x1x_regmap_write(tac5x1x, + TAC_PAGE_SELECT, 0); + if (ret < 0) { + dev_err(tac5x1x->dev, "%s, E=%d\n", + __func__, ret); + return ret; + } + + ret = tac5x1x_regmap_read(tac5x1x, reg, ref_value); + if (ret < 0) + dev_err(tac5x1x->dev, "read, ERROR, E=%d\n", + ret); + else + dev_dbg(tac5x1x->dev, + "read PAGE:REG 0x%02x:0x%02x,0x%02x\n", + TAC_PAGE_ID(reg), + TAC_PAGE_REG(reg), *ref_value); + } else { + dev_err(tac5x1x->dev, "%s, ERROR: no such device(%d)\n", + __func__, dev_no); + } + + return 0; +} + +static void tac5x1x_enable_irq(struct tac5x1x_priv *tac5x1x, bool is_enable) +{ + if (is_enable == tac5x1x->irqinfo.irq_enable && + !gpio_is_valid(tac5x1x->irqinfo.irq_gpio)) + return; + if (is_enable) + enable_irq(tac5x1x->irqinfo.irq); + else + disable_irq_nosync(tac5x1x->irqinfo.irq); + tac5x1x->irqinfo.irq_enable = is_enable; +} + +static void tac5x1x_irq_work_func(struct tac5x1x_priv *tac5x1x) +{ + u32 reg_val, array_size, i, index = 0, bit = 0; + s32 rc; + + tac5x1x_enable_irq(tac5x1x, false); + array_size = ARRAY_SIZE(int_reg_array); + for (i = 0; i < array_size; i++) { + rc = tac5x1x_dev_read(tac5x1x, index, + int_reg_array[i], ®_val); + if (!rc) { + for (s32 j = 0; j < interrupts[i].size; j++) { + bit = interrupts[i].size - 1 - j; + if (reg_val & (1 << bit)) + dev_info(tac5x1x->dev, + "Reg: %s || %s\n", + int_reg_arr_name[i], + interrupts[i].names[j]); + } + } else { + dev_err(tac5x1x->dev, + "%s DEV_NO%d Read Reg 0x%04x error(rc=%d)\n", + tac5x1x->dev_name, index, + int_reg_array[i], rc); + } + } + tac5x1x_enable_irq(tac5x1x, true); +} + +static const struct regmap_range_cfg tac5x1x_ranges[] = { + { + .range_min = 0, + .range_max = 12 * 128, + .selector_reg = TAC_PAGE_SELECT, + .selector_mask = GENMASK(7, 0), + .selector_shift = 0, + .window_start = 0, + .window_len = 128, + }, +}; + +const struct regmap_config tac5x1x_regmap = { + .max_register = 12 * 128, + .reg_bits = 8, + .val_bits = 8, + .cache_type = REGCACHE_MAPLE, + .ranges = tac5x1x_ranges, + .num_ranges = ARRAY_SIZE(tac5x1x_ranges), +}; +EXPORT_SYMBOL(tac5x1x_regmap); + +static void irq_work_routine(struct work_struct *work) +{ + struct tac5x1x_priv *tac5x1x = + container_of(work, struct tac5x1x_priv, irqinfo.irq_work.work); + + if (tac5x1x->irq_work_func) { + dev_dbg(tac5x1x->dev, "Calling irq_work_func\n"); + tac5x1x->irq_work_func(tac5x1x); + } else { + dev_dbg(tac5x1x->dev, + "%s, irq_work_func is NULL\n", __func__); + } +} + +static irqreturn_t tac5x1x_irq_handler(s32 irq, void *dev_id) +{ + struct tac5x1x_priv *tac5x1x = (struct tac5x1x_priv *)dev_id; + + /* get IRQ status after 100 ms */ + schedule_delayed_work(&tac5x1x->irqinfo.irq_work, + msecs_to_jiffies(100)); + return IRQ_HANDLED; +} + +static s32 tac5x1x_register_interrupt(struct tac5x1x_priv *tac5x1x) +{ + struct device_node *np = tac5x1x->dev->of_node; + s32 ret; + + mutex_init(&tac5x1x->dev_lock); + tac5x1x->irqinfo.irq = of_irq_get(np, 0); + INIT_DELAYED_WORK(&tac5x1x->irqinfo.irq_work, irq_work_routine); + + dev_dbg(tac5x1x->dev, "irq = %d\n", tac5x1x->irqinfo.irq); + ret = request_threaded_irq(tac5x1x->irqinfo.irq, tac5x1x_irq_handler, + NULL, IRQF_TRIGGER_FALLING, "TAC-IRQ", tac5x1x); + if (ret) { + dev_err(tac5x1x->dev, "request irq failed, ret %d\n", ret); + return ret; + } + tac5x1x->irq_work_func = tac5x1x_irq_work_func; + return 0; +}; + +static s32 tac5x1x_set_GPO1_gpio(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + s32 gpio_check, val; + + val = snd_soc_component_read(component, TAC5X1X_GPO1); + gpio_check = ((val & TAC5X1X_GPIOX_CFG_MASK) >> 0); + if (gpio_check != TAC5X1X_GPIO_GPO) { + dev_err(component->dev, + "%s: GPO1 is not configure as a GPO output\n", + __func__); + return -EINVAL; + } + + if (ucontrol->value.integer.value[0]) + val = 0; + else + val = TAC5X1X_GPO1_VAL; + + ucontrol->value.integer.value[0] = (val >> 0); + snd_soc_component_update_bits(component, TAC5X1X_GPIOVAL, + TAC5X1X_GPO1_VAL, val); + + return 1; +}; + +static s32 tac5x1x_get_GPIO1_gpio(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + s32 val; + + val = snd_soc_component_read(component, TAC5X1X_GPIOVAL); + ucontrol->value.integer.value[0] = ((val & TAC5X1X_GPIO1_MON) >> 0); + + return 0; +}; + +static s32 tac5x1x_set_GPIO1_gpio(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + s32 gpio_check, val; + + val = snd_soc_component_read(component, TAC5X1X_GPIO1); + gpio_check = ((val & TAC5X1X_GPIOX_CFG_MASK) >> 0); + if (gpio_check == TAC5X1X_GPIO_DISABLE) { + dev_err(component->dev, + "%s: GPIO1 is not configure as a GPO output\n", + __func__); + return -EINVAL; + } + + if (ucontrol->value.integer.value[0]) + val = 0; + else + val = TAC5X1X_GPIO1_VAL; + + ucontrol->value.integer.value[0] = (val >> 0); + snd_soc_component_update_bits(component, TAC5X1X_GPIOVAL, + TAC5X1X_GPIO1_VAL, val); + + return 1; +}; + +static s32 tac5x1x_get_GPIO2_gpio(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + s32 val; + + val = snd_soc_component_read(component, TAC5X1X_GPIOVAL); + ucontrol->value.integer.value[0] = !!(val & TAC5X1X_GPIO2_MON); + + return 0; +}; + +static s32 tac5x1x_set_GPIO2_gpio(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + s32 gpio_check, val; + + val = snd_soc_component_read(component, TAC5X1X_GPIO2); + gpio_check = ((val & TAC5X1X_GPIOX_CFG_MASK) >> 0); + if (gpio_check == TAC5X1X_GPIO_DISABLE) { + dev_err(component->dev, + "%s: GPIO2 is not configure as a GPO output\n", + __func__); + return -EINVAL; + } + + if (ucontrol->value.integer.value[0]) + val = 0; + else + val = TAC5X1X_GPIO2_VAL; + + ucontrol->value.integer.value[0] = (val >> 0); + snd_soc_component_update_bits(component, TAC5X1X_GPIOVAL, + TAC5X1X_GPIO2_VAL, val); + + return 1; +}; + +static s32 tac5x1x_get_GPI1_gpio(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + s32 val; + + val = snd_soc_component_read(component, TAC5X1X_GPIOVAL); + ucontrol->value.integer.value[0] = !!(val & TAC5X1X_GPI1_MON); + + return 0; +}; + +static const struct snd_kcontrol_new tac5x1x_GPO1[] = { + SOC_SINGLE_BOOL_EXT("GPO1 GPO", 0, NULL, tac5x1x_set_GPO1_gpio), +}; + +static const struct snd_kcontrol_new tac5x1x_GPIO1_I[] = { + SOC_SINGLE_BOOL_EXT("GPIO1 GPI", 0, tac5x1x_get_GPIO1_gpio, NULL), +}; + +static const struct snd_kcontrol_new tac5x1x_GPIO1_O[] = { + SOC_SINGLE_BOOL_EXT("GPIO1 GPO", 0, NULL, tac5x1x_set_GPIO1_gpio), +}; + +static const struct snd_kcontrol_new tac5x1x_GPIO2_I[] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "GPIO2 GPI", + .access = SNDRV_CTL_ELEM_ACCESS_READ, + .get = tac5x1x_get_GPIO2_gpio, + .info = snd_soc_info_bool_ext, + } +}; + +static const struct snd_kcontrol_new tac5x1x_GPIO2_O[] = { + SOC_SINGLE_BOOL_EXT("GPIO2 GPO", 0, NULL, tac5x1x_set_GPIO2_gpio), +}; + +static const struct snd_kcontrol_new tac5x1x_GPI1[] = { + SOC_SINGLE_BOOL_EXT("GPI1 GPI", 0, tac5x1x_get_GPI1_gpio, NULL), +}; + +/* Record */ +/* ADC Analog/PDM Selection */ +static const char *const tac5x1x_input_source_text[] = {"Analog", "PDM"}; + +static SOC_ENUM_SINGLE_DECL(tac5x1x_in1_source_enum, TAC5X1X_INTF4, 7, + tac5x1x_input_source_text); +static SOC_ENUM_SINGLE_DECL(tac5x1x_in2_source_enum, TAC5X1X_INTF4, 6, + tac5x1x_input_source_text); + +static const struct snd_kcontrol_new tac5x1x_dapm_in1_source_control[] = { + SOC_DAPM_ENUM("CH1 Source MUX", tac5x1x_in1_source_enum), +}; + +static const struct snd_kcontrol_new tac5x1x_dapm_in2_source_control[] = { + SOC_DAPM_ENUM("CH2 Source MUX", tac5x1x_in2_source_enum), +}; + +static const char *const tad5x1x_input_source_text[] = {"Disable", "PDM"}; +static SOC_ENUM_SINGLE_DECL(tad5x1x_in1_source_enum, TAC5X1X_INTF4, 7, + tad5x1x_input_source_text); +static SOC_ENUM_SINGLE_DECL(tad5x1x_in2_source_enum, TAC5X1X_INTF4, 6, + tad5x1x_input_source_text); + +static const struct snd_kcontrol_new tad5x1x_dapm_in1_source_control[] = { + SOC_DAPM_ENUM("CH1 Source MUX", tad5x1x_in1_source_enum), +}; + +static const struct snd_kcontrol_new tad5x1x_dapm_in2_source_control[] = { + SOC_DAPM_ENUM("CH2 Source MUX", tad5x1x_in2_source_enum), +}; + +/* ADC Analog source Selection */ +static const char *const tac5x1x_input_analog_sel_text[] = { + "Differential", + "Single-ended", + "Single-ended mux INxP", + "Single-ended mux INxM", +}; + +static const char *const tac5x1x_input_analog2_sel_text[] = { + "Differential", + "Single-ended", +}; + +static SOC_ENUM_SINGLE_DECL(tac5x1x_adc1_config_enum, TAC5X1X_ADCCH1C0, 6, + tac5x1x_input_analog_sel_text); +static SOC_ENUM_SINGLE_DECL(tac5x1x_adc2_config_enum, TAC5X1X_ADCCH2C0, 6, + tac5x1x_input_analog2_sel_text); + +static const struct snd_kcontrol_new tac5x1x_dapm_adc1_config_control[] = { + SOC_DAPM_ENUM("ADC1 Analog MUX", tac5x1x_adc1_config_enum), +}; + +static const struct snd_kcontrol_new tac5x1x_dapm_adc2_config_control[] = { + SOC_DAPM_ENUM("ADC2 Analog MUX", tac5x1x_adc2_config_enum), +}; + +/* + * ADC full-scale selection + * 2/10-VRMS is for TAX52xx/TAX51xx devices + * 4/5-VRMS is for TAX54xx/TAX53xx devices + */ +static const char *const tac5x1x_adc_fscale_text[] = {"2/10-VRMS", + "4/5-VRMS"}; + +static SOC_ENUM_SINGLE_DECL(tac5x1x_adc1_fscale_enum, TAC5X1X_ADCCH1C0, 1, + tac5x1x_adc_fscale_text); +static SOC_ENUM_SINGLE_DECL(tac5x1x_adc2_fscale_enum, TAC5X1X_ADCCH2C0, 1, + tac5x1x_adc_fscale_text); + +static const struct snd_kcontrol_new tac5x1x_dapm_adc1_fscale_control[] = { + SOC_DAPM_ENUM("ADC1 FSCALE MUX", tac5x1x_adc1_fscale_enum), +}; + +static const struct snd_kcontrol_new tac5x1x_dapm_adc2_fscale_control[] = { + SOC_DAPM_ENUM("ADC2 FSCALE MUX", tac5x1x_adc2_fscale_enum), +}; + +/* Impedance Selection */ +static const char *const resistor_text[] = { + "5 kOhm", + "10 kOhm", + "40 kOhm", +}; + +static SOC_ENUM_SINGLE_DECL(adc1_resistor_enum, TAC5X1X_ADCCH1C0, 4, + resistor_text); +static SOC_ENUM_SINGLE_DECL(adc2_resistor_enum, TAC5X1X_ADCCH2C0, 4, + resistor_text); + +/* PDM Data input pin Selection */ +static const char *const pdm_pin_text[] = { + "Disable", + "GPIO1", + "GPIO2", + "GPI1", +}; + +static SOC_ENUM_SINGLE_DECL(pdm_12_pin_enum, TAC5X1X_INTF4, 2, pdm_pin_text); +static SOC_ENUM_SINGLE_DECL(pdm_34_pin_enum, TAC5X1X_INTF4, 0, pdm_pin_text); +static const struct snd_kcontrol_new pdm_12_pin_controls[] = { + SOC_DAPM_ENUM("PDM chn12 Datain Select", pdm_12_pin_enum), +}; + +static const struct snd_kcontrol_new pdm_34_pin_controls[] = { + SOC_DAPM_ENUM("PDM chn34 Datain Select", pdm_34_pin_enum), +}; + +static const char *const pdmclk_text[] = { + "2.8224 MHz or 3.072 MHz", "1.4112 MHz or 1.536 MHz", + "705.6 kHz or 768 kHz", "5.6448 MHz or 6.144 MHz"}; + +static SOC_ENUM_SINGLE_DECL(pdmclk_select_enum, TAC5X1X_CNTCLK0, 6, + pdmclk_text); + +/* Digital Volume control. From -80 to 47 dB in 0.5 dB steps */ +static DECLARE_TLV_DB_SCALE(record_dig_vol_tlv, -8000, 50, 0); + +/* Gain Calibration control. From -0.8db to 0.7db dB in 0.1 dB steps */ +static DECLARE_TLV_DB_MINMAX(record_gain_cali_tlv, -80, 70); + +/* Analog Level control. From -12 to 24 dB in 6 dB steps */ +static DECLARE_TLV_DB_SCALE(playback_analog_level_tlv, -1200, 600, 0); + +/* Digital Volume control. From -100 to 27 dB in 0.5 dB steps */ +static DECLARE_TLV_DB_SCALE(dac_dig_vol_tlv, -10000, 50, 0); // mute ? + +/* Gain Calibration control. From -0.8db to 0.7db dB in 0.1 dB steps */ +static DECLARE_TLV_DB_MINMAX(playback_gain_cali_tlv, -80, 70); + +/* Output Source Selection */ +static const char *const tac5x1x_output_source_text[] = { + "Disabled", + "DAC Input", + "Analog Bypass", + "DAC + Analog Bypass Mix", + "DAC -> OUTxP, INxP -> OUTxM", + "INxM -> OUTxP, DAC -> OUTxM", +}; + +static SOC_ENUM_SINGLE_DECL(tac5x1x_out1_source_enum, TAC5X1X_OUT1CFG0, 5, + tac5x1x_output_source_text); +static SOC_ENUM_SINGLE_DECL(tac5x1x_out2_source_enum, TAC5X1X_OUT2CFG0, 5, + tac5x1x_output_source_text); + +static const struct snd_kcontrol_new tac5x1x_dapm_out1_source_control[] = { + SOC_DAPM_ENUM("OUT1X MUX", tac5x1x_out1_source_enum), +}; + +static const struct snd_kcontrol_new tac5x1x_dapm_out2_source_control[] = { + SOC_DAPM_ENUM("OUT2X MUX", tac5x1x_out2_source_enum), +}; + +/* Output Config Selection */ +static const char *const tac5x1x_output_config_text[] = { + "Differential", + "Stereo Single-ended", + "Mono Single-ended at OUTxP only", + "Mono Single-ended at OUTxM only", + "Pseudo differential with OUTxM as VCOM", + "Pseudo differential with OUTxM as external sensing", + "Pseudo differential with OUTxP as VCOM", +}; + +static const char *const tac5x1x_output2_config_text[] = { + "Differential", + "Stereo Single-ended", + "Mono Single-ended at OUTxP only", + "Mono Single-ended at OUTxM only", + "Pseudo differential with OUTxM as VCOM", + "Reserved", + "Pseudo differential with OUTxP as VCOM", +}; + +static SOC_ENUM_SINGLE_DECL(tac5x1x_out1_config_enum, TAC5X1X_OUT1CFG0, 2, + tac5x1x_output_config_text); +static SOC_ENUM_SINGLE_DECL(tac5x1x_out2_config_enum, TAC5X1X_OUT2CFG0, 2, + tac5x1x_output2_config_text); + +static const struct snd_kcontrol_new tac5x1x_dapm_out1_config_control[] = { + SOC_DAPM_ENUM("OUT1X Config MUX", tac5x1x_out1_config_enum), +}; + +static const struct snd_kcontrol_new tac5x1x_dapm_out2_config_control[] = { + SOC_DAPM_ENUM("OUT2X Config MUX", tac5x1x_out2_config_enum), +}; + +static const char *const tac5x1x_wideband_text[] = { + "Audio BW 24-kHz", + "Wide BW 96-kHz", +}; + +static SOC_ENUM_SINGLE_DECL(tac5x1x_adc1_wideband_enum, TAC5X1X_ADCCH1C0, 0, + tac5x1x_wideband_text); +static SOC_ENUM_SINGLE_DECL(tac5x1x_adc2_wideband_enum, TAC5X1X_ADCCH2C0, 0, + tac5x1x_wideband_text); +static SOC_ENUM_SINGLE_DECL(tac5x1x_dac1_wideband_enum, TAC5X1X_OUT1CFG1, 0, + tac5x1x_wideband_text); +static SOC_ENUM_SINGLE_DECL(tac5x1x_dac2_wideband_enum, TAC5X1X_OUT2CFG1, 0, + tac5x1x_wideband_text); + +static const char *const tac5x1x_tolerance_text[] = { + "AC Coupled with 100mVpp", + "AC/DC Coupled with 1Vpp", + "AC/DC Coupled with Rail-to-rail", +}; + +static SOC_ENUM_SINGLE_DECL(tac5x1x_adc1_tolerance_enum, TAC5X1X_ADCCH1C0, 2, + tac5x1x_tolerance_text); +static SOC_ENUM_SINGLE_DECL(tac5x1x_adc2_tolerance_enum, TAC5X1X_ADCCH2C0, 2, + tac5x1x_tolerance_text); + +/* Output Drive Selection */ +static const char *const tac5x1x_output_driver_text[] = { + "Line-out", + "Headphone", + "4 ohm", + "FD Receiver/Debug", +}; + +static SOC_ENUM_SINGLE_DECL(out1p_driver_enum, TAC5X1X_OUT1CFG1, 6, + tac5x1x_output_driver_text); + +static SOC_ENUM_SINGLE_DECL(out2p_driver_enum, TAC5X1X_OUT2CFG1, 6, + tac5x1x_output_driver_text); + +static const struct snd_kcontrol_new tac5x1x_dapm_out1_driver_control[] = { + SOC_DAPM_ENUM("OUT1 driver MUX", out1p_driver_enum), +}; + +static const struct snd_kcontrol_new tac5x1x_dapm_out2_driver_control[] = { + SOC_DAPM_ENUM("OUT2 driver MUX", out2p_driver_enum), +}; + +/* Decimation Filter Selection */ +static const char *const decimation_filter_text[] = { + "Linear Phase", "Low Latency", "Ultra-low Latency"}; + +static SOC_ENUM_SINGLE_DECL(decimation_filter_record_enum, TAC5X1X_DSP0, 6, + decimation_filter_text); +static SOC_ENUM_SINGLE_DECL(decimation_filter_playback_enum, TAC5X1X_DSP1, 6, + decimation_filter_text); + +static const struct snd_kcontrol_new tx_ch1_asi_switch = + SOC_DAPM_SINGLE("Capture Switch", TAC5X1X_PASITXCH1, 5, 1, 0); +static const struct snd_kcontrol_new tx_ch2_asi_switch = + SOC_DAPM_SINGLE("Capture Switch", TAC5X1X_PASITXCH2, 5, 1, 0); +static const struct snd_kcontrol_new tx_ch3_asi_switch = + SOC_DAPM_SINGLE("Capture Switch", TAC5X1X_PASITXCH3, 5, 1, 0); +static const struct snd_kcontrol_new tx_ch4_asi_switch = + SOC_DAPM_SINGLE("Capture Switch", TAC5X1X_PASITXCH4, 5, 1, 0); + +static const struct snd_kcontrol_new rx_ch1_asi_switch = + SOC_DAPM_SINGLE("Switch", TAC5X1X_PASIRXCH1, 5, 1, 0); +static const struct snd_kcontrol_new rx_ch2_asi_switch = + SOC_DAPM_SINGLE("Switch", TAC5X1X_PASIRXCH2, 5, 1, 0); + +static const char *const rx_ch3_asi_cfg_text[] = { + "Disable", + "DAC channel data", +}; + +static const char *const rx_ch5_asi_cfg_text[] = { + "Disable", + "DAC channel data", + "ADC channel output loopback", +}; + +static const char *const rx_ch6_asi_cfg_text[] = { + "Disable", + "DAC channel data", + "ADC channel output loopback", + "Channel Input to ICLA device", +}; + +static const char *const tx_ch5_asi_cfg_text[] = { + "Tristate", + "Input Channel Loopback data", + "Echo reference Channel data", +}; + +static const char *const tx_ch7_asi_cfg_text[] = { + "Tristate", + "Vbat_Wlby2,Temp_Wlby2", + "echo_ref_ch1,echo_ref_ch2", +}; + +static const char *const tx_ch8_asi_cfg_text[] = { + "Tristate", + "ICLA data", +}; + +static const char *const tac5x1x_slot_select_text[] = { + "Slot 0", "Slot 1", "Slot 2", "Slot 3", + "Slot 4", "Slot 5", "Slot 6", "Slot 7", + "Slot 8", "Slot 9", "Slot 10", "Slot 11", + "Slot 12", "Slot 13", "Slot 14", "Slot 15", + "Slot 16", "Slot 17", "Slot 18", "Slot 19", + "Slot 20", "Slot 21", "Slot 22", "Slot 23", + "Slot 24", "Slot 25", "Slot 26", "Slot 27", + "Slot 28", "Slot 29", "Slot 30", "Slot 31", +}; + +static const char *const out2x_vcom_text[] = { + "0.6 * Vref", + "AVDD by 2", +}; + +static const char *const diag_cfg_text[] = { + "0mv", "30mv", "60mv", "90mv", + "120mv", "150mv", "180mv", "210mv", + "240mv", "270mv", "300mv", "330mv", + "360mv", "390mv", "420mv", "450mv", +}; + +static const char *const diag_cfg_gnd_text[] = { + "0mv", "60mv", "120mv", "180mv", + "240mv", "300mv", "360mv", "420mv", + "480mv", "540mv", "600mv", "660mv", + "720mv", "780mv", "840mv", "900mv", +}; + +static SOC_ENUM_SINGLE_DECL(out2x_vcom_enum, TAC5X1X_OUT2CFG0, 1, + out2x_vcom_text); + +static SOC_ENUM_SINGLE_DECL(tx_ch5_asi_cfg_enum, TAC5X1X_PASITXCH5, 5, + tx_ch5_asi_cfg_text); +static SOC_ENUM_SINGLE_DECL(tx_ch6_asi_cfg_enum, TAC5X1X_PASITXCH6, 5, + tx_ch5_asi_cfg_text); +static SOC_ENUM_SINGLE_DECL(tx_ch7_asi_cfg_enum, TAC5X1X_PASITXCH7, 5, + tx_ch7_asi_cfg_text); +static SOC_ENUM_SINGLE_DECL(tx_ch8_asi_cfg_enum, TAC5X1X_PASITXCH8, 5, + tx_ch8_asi_cfg_text); +static SOC_ENUM_SINGLE_DECL(tx_ch1_slot_select_enum, TAC5X1X_PASITXCH1, 0, + tac5x1x_slot_select_text); +static SOC_ENUM_SINGLE_DECL(tx_ch2_slot_select_enum, TAC5X1X_PASITXCH2, 0, + tac5x1x_slot_select_text); +static SOC_ENUM_SINGLE_DECL(tx_ch3_slot_select_enum, TAC5X1X_PASITXCH3, 0, + tac5x1x_slot_select_text); +static SOC_ENUM_SINGLE_DECL(tx_ch4_slot_select_enum, TAC5X1X_PASITXCH4, 0, + tac5x1x_slot_select_text); +static SOC_ENUM_SINGLE_DECL(tx_ch5_slot_select_enum, TAC5X1X_PASITXCH5, 0, + tac5x1x_slot_select_text); +static SOC_ENUM_SINGLE_DECL(tx_ch6_slot_select_enum, TAC5X1X_PASITXCH6, 0, + tac5x1x_slot_select_text); +static SOC_ENUM_SINGLE_DECL(tx_ch7_slot_select_enum, TAC5X1X_PASITXCH7, 0, + tac5x1x_slot_select_text); +static SOC_ENUM_SINGLE_DECL(tx_ch8_slot_select_enum, TAC5X1X_PASITXCH8, 0, + tac5x1x_slot_select_text); + +static SOC_ENUM_SINGLE_DECL(rx_ch3_asi_cfg_enum, TAC5X1X_PASIRXCH3, 5, + rx_ch3_asi_cfg_text); +static SOC_ENUM_SINGLE_DECL(rx_ch4_asi_cfg_enum, TAC5X1X_PASIRXCH4, 5, + rx_ch3_asi_cfg_text); +static SOC_ENUM_SINGLE_DECL(rx_ch5_asi_cfg_enum, TAC5X1X_PASIRXCH5, 5, + rx_ch5_asi_cfg_text); +static SOC_ENUM_SINGLE_DECL(rx_ch6_asi_cfg_enum, TAC5X1X_PASIRXCH6, 5, + rx_ch6_asi_cfg_text); +static SOC_ENUM_SINGLE_DECL(rx_ch7_asi_cfg_enum, TAC5X1X_PASIRXCH7, 5, + rx_ch6_asi_cfg_text); +static SOC_ENUM_SINGLE_DECL(rx_ch8_asi_cfg_enum, TAC5X1X_PASIRXCH8, 5, + rx_ch6_asi_cfg_text); + +static SOC_ENUM_SINGLE_DECL(rx_ch1_slot_select_enum, TAC5X1X_PASIRXCH1, 0, + tac5x1x_slot_select_text); +static SOC_ENUM_SINGLE_DECL(rx_ch2_slot_select_enum, TAC5X1X_PASIRXCH2, 0, + tac5x1x_slot_select_text); +static SOC_ENUM_SINGLE_DECL(rx_ch3_slot_select_enum, TAC5X1X_PASIRXCH3, 0, + tac5x1x_slot_select_text); +static SOC_ENUM_SINGLE_DECL(rx_ch4_slot_select_enum, TAC5X1X_PASIRXCH4, 0, + tac5x1x_slot_select_text); +static SOC_ENUM_SINGLE_DECL(rx_ch5_slot_select_enum, TAC5X1X_PASIRXCH5, 0, + tac5x1x_slot_select_text); +static SOC_ENUM_SINGLE_DECL(rx_ch6_slot_select_enum, TAC5X1X_PASIRXCH6, 0, + tac5x1x_slot_select_text); +static SOC_ENUM_SINGLE_DECL(rx_ch7_slot_select_enum, TAC5X1X_PASIRXCH7, 0, + tac5x1x_slot_select_text); +static SOC_ENUM_SINGLE_DECL(rx_ch8_slot_select_enum, TAC5X1X_PASIRXCH8, 0, + tac5x1x_slot_select_text); + +static SOC_ENUM_SINGLE_DECL(diag_cfg1_sht_term_enum, TAC5X1X_DIAG_CFG1, 4, + diag_cfg_text); +static SOC_ENUM_SINGLE_DECL(diag_cfg1_vbat_in_enum, TAC5X1X_DIAG_CFG1, 0, + diag_cfg_text); +static SOC_ENUM_SINGLE_DECL(diag_cfg2_sht_gnd_enum, TAC5X1X_DIAG_CFG2, 4, + diag_cfg_gnd_text); +static SOC_ENUM_SINGLE_DECL(diag_cfg2_micbias, TAC5X1X_DIAG_CFG2, 0, + diag_cfg_text); + +static const struct snd_kcontrol_new taa5x1x_controls[] = { + SOC_ENUM("Record Decimation Filter", + decimation_filter_record_enum), + SOC_ENUM("ADC1 Audio BW", tac5x1x_adc1_wideband_enum), + + SOC_SINGLE_TLV("ADC1 Digital Capture Volume", TAC5X1X_ADCCH1C2, + 0, 0xff, 0, record_dig_vol_tlv), + + SOC_SINGLE_TLV("ADC1 Fine Capture Volume", TAC5X1X_ADCCH1C3, + 0, 0xff, 0, record_gain_cali_tlv), + + SOC_SINGLE_RANGE("ADC1 Phase Capture Volume", TAC5X1X_ADCCH1C4, + 2, 0, 63, 0), + + SOC_ENUM("ASI_TX_CH5_CFG", tx_ch5_asi_cfg_enum), + SOC_ENUM("ASI_TX_CH6_CFG", tx_ch6_asi_cfg_enum), + SOC_ENUM("ASI_TX_CH7_CFG", tx_ch7_asi_cfg_enum), + SOC_ENUM("ASI_TX_CH8_CFG", tx_ch8_asi_cfg_enum), + SOC_ENUM("ASI_TX_CH1_SLOT", tx_ch1_slot_select_enum), + SOC_ENUM("ASI_TX_CH2_SLOT", tx_ch2_slot_select_enum), + SOC_ENUM("ASI_TX_CH3_SLOT", tx_ch3_slot_select_enum), + SOC_ENUM("ASI_TX_CH4_SLOT", tx_ch4_slot_select_enum), + SOC_ENUM("ASI_TX_CH5_SLOT", tx_ch5_slot_select_enum), + SOC_ENUM("ASI_TX_CH6_SLOT", tx_ch6_slot_select_enum), + SOC_ENUM("ASI_TX_CH7_SLOT", tx_ch7_slot_select_enum), + SOC_ENUM("ASI_TX_CH8_SLOT", tx_ch8_slot_select_enum), + SOC_SINGLE("IN_CH1_EN Capture Switch", TAC5X1X_CH_EN, 7, 1, 0), + SOC_SINGLE("IN_CH2_EN Capture Switch", TAC5X1X_CH_EN, 6, 1, 0), + SOC_SINGLE("IN_CH3_EN Capture Switch", TAC5X1X_CH_EN, 5, 1, 0), + SOC_SINGLE("IN_CH4_EN Capture Switch", TAC5X1X_CH_EN, 4, 1, 0), +}; + +static const struct snd_kcontrol_new tad5x1x_controls[] = { + SOC_ENUM("Playback Decimation Filter", + decimation_filter_playback_enum), + SOC_ENUM("DAC1 Audio BW", tac5x1x_dac1_wideband_enum), + SOC_SINGLE_TLV("OUT1P Analog Level Playback Volume", TAC5X1X_OUT1CFG1, + 3, 6, 1, playback_analog_level_tlv), + SOC_SINGLE_TLV("OUT1M Analog Level Playback Volume", TAC5X1X_OUT1CFG2, + 3, 6, 1, playback_analog_level_tlv), + SOC_SINGLE_TLV("DAC1 CHA Digital Playback Volume", TAC5X1X_DACCH1A0, + 0, 0xff, 0, dac_dig_vol_tlv), + SOC_SINGLE_TLV("DAC1 CHB Digital Playback Volume", TAC5X1X_DACCH1B0, + 0, 0xff, 0, dac_dig_vol_tlv), + SOC_SINGLE_TLV("DAC1 CHA Gain Calibration Playback Volume", + TAC5X1X_DACCH1A1, 4, 0xf, 0, + playback_gain_cali_tlv), + SOC_SINGLE_TLV("DAC1 CHB Gain Calibration Playback Volume", + TAC5X1X_DACCH1B1, 4, 0xf, 0, + playback_gain_cali_tlv), + + SOC_ENUM("ASI_RX_CH3_EN Playback", rx_ch3_asi_cfg_enum), + SOC_ENUM("ASI_RX_CH4_EN Playback", rx_ch4_asi_cfg_enum), + SOC_ENUM("ASI_RX_CH5_EN Playback", rx_ch5_asi_cfg_enum), + SOC_ENUM("ASI_RX_CH6_EN Playback", rx_ch6_asi_cfg_enum), + SOC_ENUM("ASI_RX_CH7_EN Playback", rx_ch7_asi_cfg_enum), + SOC_ENUM("ASI_RX_CH8_EN Playback", rx_ch8_asi_cfg_enum), + SOC_ENUM("ASI_RX_CH1_SLOT Playback", rx_ch1_slot_select_enum), + SOC_ENUM("ASI_RX_CH2_SLOT Playback", rx_ch2_slot_select_enum), + SOC_ENUM("ASI_RX_CH3_SLOT Playback", rx_ch3_slot_select_enum), + SOC_ENUM("ASI_RX_CH4_SLOT Playback", rx_ch4_slot_select_enum), + SOC_ENUM("ASI_RX_CH5_SLOT Playback", rx_ch5_slot_select_enum), + SOC_ENUM("ASI_RX_CH6_SLOT Playback", rx_ch6_slot_select_enum), + SOC_ENUM("ASI_RX_CH7_SLOT Playback", rx_ch7_slot_select_enum), + SOC_ENUM("ASI_RX_CH8_SLOT Playback", rx_ch8_slot_select_enum), + + SOC_SINGLE("OUT_CH1_EN Playback Switch", TAC5X1X_CH_EN, 3, 1, 0), + SOC_SINGLE("OUT_CH2_EN Playback Switch", TAC5X1X_CH_EN, 2, 1, 0), + SOC_SINGLE("OUT_CH3_EN Playback Switch", TAC5X1X_CH_EN, 1, 1, 0), + SOC_SINGLE("OUT_CH4_EN Playback Switch", TAC5X1X_CH_EN, 0, 1, 0), +}; + +static const struct snd_kcontrol_new tac5x11_controls[] = { + SOC_ENUM("ADC1 Common-mode Tolerance", tac5x1x_adc1_tolerance_enum), + SOC_ENUM("ADC1 Impedance Select", adc1_resistor_enum), +}; + +static const struct snd_kcontrol_new tad5x12_controls[] = { + SOC_SINGLE_TLV("OUT2P Analog Level Playback Volume", TAC5X1X_OUT2CFG1, + 3, 6, 1, playback_analog_level_tlv), + SOC_SINGLE_TLV("OUT2M Analog Level Playback Volume", TAC5X1X_OUT2CFG2, + 3, 6, 1, playback_analog_level_tlv), + SOC_SINGLE_TLV("DAC2 CHA Digital Playback Volume", TAC5X1X_DACCH2A0, + 0, 0xff, 0, dac_dig_vol_tlv), + SOC_SINGLE_TLV("DAC2 CHB Digital Playback Volume", TAC5X1X_DACCH2B0, + 0, 0xff, 0, dac_dig_vol_tlv), + SOC_SINGLE_TLV("DAC2 CHA Gain Calibration Playback Volume", + TAC5X1X_DACCH2A1, 4, 0xf, 0, + playback_gain_cali_tlv), + SOC_SINGLE_TLV("DAC2 CHB Gain Calibration Playback Volume", + TAC5X1X_DACCH2B1, 4, 0xf, 0, + playback_gain_cali_tlv), + SOC_ENUM("DAC2 Audio BW", tac5x1x_dac2_wideband_enum), + SOC_ENUM("OUT2X_VCOM", out2x_vcom_enum), +}; + +static const struct snd_kcontrol_new taa5x12_controls[] = { + SOC_ENUM("ADC2 Audio BW", tac5x1x_adc2_wideband_enum), + + SOC_SINGLE_TLV("ADC2 Digital Capture Volume", TAC5X1X_ADCCH2C2, + 0, 0xff, 0, record_dig_vol_tlv), + + SOC_SINGLE_TLV("ADC2 Fine Capture Volume", TAC5X1X_ADCCH2C3, + 0, 0xff, 0, record_gain_cali_tlv), + + SOC_SINGLE_RANGE("ADC2 Phase Capture Volume", TAC5X1X_ADCCH2C4, + 2, 0, 63, 0), +}; + +static const struct snd_kcontrol_new tac5x12_impedance_controls[] = { + SOC_ENUM("ADC1 Impedance Select", adc1_resistor_enum), + SOC_ENUM("ADC2 Impedance Select", adc2_resistor_enum), +}; + +static const struct snd_kcontrol_new tac5x12_tolerance_controls[] = { + SOC_ENUM("ADC1 Common-mode Tolerance", tac5x1x_adc1_tolerance_enum), + SOC_ENUM("ADC2 Common-mode Tolerance", tac5x1x_adc2_tolerance_enum), +}; + +static const struct snd_kcontrol_new tac5x1x_pdm_controls[] = { + SOC_ENUM("PDM Clk Divider", pdmclk_select_enum), + + SOC_SINGLE_TLV("PDM1 Digital Capture Volume", TAC5X1X_ADCCH1C2, + 0, 0xff, 0, record_dig_vol_tlv), + SOC_SINGLE_TLV("PDM2 Digital Capture Volume", TAC5X1X_ADCCH2C2, + 0, 0xff, 0, record_dig_vol_tlv), + + SOC_SINGLE_TLV("PDM1 Fine Capture Volume", TAC5X1X_ADCCH1C3, + 0, 0xff, 0, record_gain_cali_tlv), + SOC_SINGLE_TLV("PDM2 Fine Capture Volume", TAC5X1X_ADCCH2C3, + 0, 0xff, 0, record_gain_cali_tlv), + + SOC_SINGLE_RANGE("PDM1 Phase Capture Volume", TAC5X1X_ADCCH1C4, + 2, 0, 63, 0), + SOC_SINGLE_RANGE("PDM2 Phase Capture Volume", TAC5X1X_ADCCH2C4, + 2, 0, 63, 0), + + SOC_SINGLE_TLV("PDM3 Digital Capture Volume", TAC5X1X_ADCCH3C2, + 0, 0xff, 0, record_dig_vol_tlv), + SOC_SINGLE_TLV("PDM4 Digital Capture Volume", TAC5X1X_ADCCH4C2, + 0, 0xff, 0, record_dig_vol_tlv), + + SOC_SINGLE_TLV("PDM3 Fine Capture Volume", TAC5X1X_ADCCH3C3, + 0, 0xff, 0, record_gain_cali_tlv), + SOC_SINGLE_TLV("PDM4 Fine Capture Volume", TAC5X1X_ADCCH4C3, + 0, 0xff, 0, record_gain_cali_tlv), + + SOC_SINGLE_RANGE("PDM3 Phase Capture Volume", TAC5X1X_ADCCH3C4, + 2, 0, 63, 0), + SOC_SINGLE_RANGE("PDM4 Phase Capture Volume", TAC5X1X_ADCCH4C4, + 2, 0, 63, 0), +}; + +static const struct snd_kcontrol_new taa5x1x_ip_controls[] = { + SOC_ENUM("DIAG_SHT_TERM", diag_cfg1_sht_term_enum), + SOC_ENUM("DIAG_SHT_VBAT_IN", diag_cfg1_vbat_in_enum), + SOC_ENUM("DIAG_SHT_GND", diag_cfg2_sht_gnd_enum), + SOC_ENUM("DIAG_SHT_MICBIAS", diag_cfg2_micbias), +}; + +static const struct snd_soc_dapm_widget taa5x1x_dapm_widgets[] = { + /* ADC1 */ + SND_SOC_DAPM_INPUT("AIN1"), + + SND_SOC_DAPM_MUX("ADC1 Full-Scale", SND_SOC_NOPM, 0, 0, + tac5x1x_dapm_adc1_fscale_control), + + SND_SOC_DAPM_MUX("ADC1 Config", SND_SOC_NOPM, 0, 0, + tac5x1x_dapm_adc1_config_control), + + SND_SOC_DAPM_ADC("CH1_ADC_EN", "CH1 Capture", TAC5X1X_CH_EN, 7, 0), + + SND_SOC_DAPM_SWITCH("ASI_TX_CH1_EN", SND_SOC_NOPM, 0, 0, + &tx_ch1_asi_switch), + + SND_SOC_DAPM_MICBIAS("Mic Bias", TAC5X1X_PWR_CFG, 5, 0), + SND_SOC_DAPM_SWITCH("ASI_TX_CH2_EN", SND_SOC_NOPM, 0, 0, + &tx_ch2_asi_switch), +}; + +static const struct snd_kcontrol_new tad5x1x_pdm_controls[] = { + SOC_ENUM("ASI_TX_CH1_SLOT", tx_ch1_slot_select_enum), + SOC_ENUM("ASI_TX_CH2_SLOT", tx_ch2_slot_select_enum), + SOC_ENUM("ASI_TX_CH3_SLOT", tx_ch3_slot_select_enum), + SOC_ENUM("ASI_TX_CH4_SLOT", tx_ch4_slot_select_enum), +}; + +static const struct snd_soc_dapm_widget tad5xx_dapm_widgets[] = { + /* pdm capture */ + SND_SOC_DAPM_SWITCH("ASI_TX_CH1_EN", SND_SOC_NOPM, 0, 0, + &tx_ch1_asi_switch), + SND_SOC_DAPM_SWITCH("ASI_TX_CH2_EN", SND_SOC_NOPM, 0, 0, + &tx_ch2_asi_switch), +}; + +static const struct snd_soc_dapm_widget tad5x1x_dapm_widgets[] = { + /* DAC1 */ + SND_SOC_DAPM_AIF_IN("ASI IN1", "ASI Playback", 0, SND_SOC_NOPM, 0, 0), + + SND_SOC_DAPM_OUTPUT("OUT1"), + + SND_SOC_DAPM_MUX("OUT1x Source", SND_SOC_NOPM, 0, 0, + tac5x1x_dapm_out1_source_control), + + SND_SOC_DAPM_MUX("OUT1x Config", SND_SOC_NOPM, 0, 0, + tac5x1x_dapm_out1_config_control), + + SND_SOC_DAPM_MUX("OUT1x Driver", SND_SOC_NOPM, 0, 0, + tac5x1x_dapm_out1_driver_control), + + SND_SOC_DAPM_DAC("Left DAC Enable", "Left Playback", TAC5X1X_CH_EN, 3, + 0), + SND_SOC_DAPM_PGA("Left DAC Power", TAC5X1X_PWR_CFG, 6, 0, NULL, 0), + + SND_SOC_DAPM_SWITCH("ASI_RX_CH1_EN", SND_SOC_NOPM, 0, 0, + &rx_ch1_asi_switch), +}; + +static const struct snd_soc_dapm_widget taa5x12_dapm_widgets[] = { + /* ADC2 */ + SND_SOC_DAPM_INPUT("AIN2"), + + SND_SOC_DAPM_MUX("ADC2 Full-Scale", SND_SOC_NOPM, 0, 0, + tac5x1x_dapm_adc2_fscale_control), + + SND_SOC_DAPM_MUX("ADC2 Config", SND_SOC_NOPM, 0, 0, + tac5x1x_dapm_adc2_config_control), + + SND_SOC_DAPM_ADC("CH2_ADC_EN", "CH2 Capture", TAC5X1X_CH_EN, 6, 0), + +}; + +static const struct snd_soc_dapm_widget tad5x12_dapm_widgets[] = { + /* DAC2 */ + SND_SOC_DAPM_OUTPUT("OUT2"), + + SND_SOC_DAPM_AIF_IN("ASI IN2", "ASI Playback", 0, SND_SOC_NOPM, 0, 0), + + SND_SOC_DAPM_MUX("OUT2x Source", SND_SOC_NOPM, 0, 0, + tac5x1x_dapm_out2_source_control), + + SND_SOC_DAPM_MUX("OUT2x Config", SND_SOC_NOPM, 0, 0, + tac5x1x_dapm_out2_config_control), + + SND_SOC_DAPM_MUX("OUT2x Driver", SND_SOC_NOPM, 0, 0, + tac5x1x_dapm_out2_driver_control), + + SND_SOC_DAPM_DAC("Right DAC Enable", + "Right Playback", TAC5X1X_CH_EN, 2, 0), + SND_SOC_DAPM_PGA("Right DAC Power", TAC5X1X_PWR_CFG, 6, 0, NULL, 0), + + SND_SOC_DAPM_SWITCH("ASI_RX_CH2_EN", SND_SOC_NOPM, 0, 0, + &rx_ch2_asi_switch), +}; + +static const struct snd_soc_dapm_widget tac5x1x_dapm_pdm_widgets[] = { + /* PDM */ + SND_SOC_DAPM_INPUT("DIN1"), + SND_SOC_DAPM_INPUT("DIN2"), + SND_SOC_DAPM_INPUT("DIN3"), + SND_SOC_DAPM_INPUT("DIN4"), + + SND_SOC_DAPM_MUX("PDM ch1 & ch2 Datain Select", + SND_SOC_NOPM, 0, 0, pdm_12_pin_controls), + SND_SOC_DAPM_MUX("PDM ch3 & ch4 Datain Select", + SND_SOC_NOPM, 0, 0, pdm_34_pin_controls), + + SND_SOC_DAPM_ADC("CH1_PDM_EN", "PDM CH1 Capture", TAC5X1X_CH_EN, 7, 0), + SND_SOC_DAPM_ADC("CH2_PDM_EN", "PDM CH2 Capture", TAC5X1X_CH_EN, 6, 0), + SND_SOC_DAPM_ADC("CH3_PDM_EN", "PDM CH3 Capture", TAC5X1X_CH_EN, 5, 0), + SND_SOC_DAPM_ADC("CH4_PDM_EN", "PDM CH4 Capture", TAC5X1X_CH_EN, 4, 0), + + SND_SOC_DAPM_SWITCH("ASI_TX_CH3_EN", SND_SOC_NOPM, 0, 0, + &tx_ch3_asi_switch), + SND_SOC_DAPM_SWITCH("ASI_TX_CH4_EN", SND_SOC_NOPM, 0, 0, + &tx_ch4_asi_switch), +}; + +static const struct snd_soc_dapm_widget tac5x1x_common_dapm_widgets[] = { + SND_SOC_DAPM_MUX("IN1 Source Mux", SND_SOC_NOPM, 0, 0, + tac5x1x_dapm_in1_source_control), + SND_SOC_DAPM_MUX("IN2 Source Mux", SND_SOC_NOPM, 0, 0, + tac5x1x_dapm_in2_source_control), + SND_SOC_DAPM_PGA("ADC Power", TAC5X1X_PWR_CFG, 7, 0, NULL, 0), + SND_SOC_DAPM_AIF_OUT("AIF OUT", "ASI Capture", 0, SND_SOC_NOPM, 0, 0), +}; + +static const struct snd_soc_dapm_widget tad5x1x_common_dapm_widgets[] = { + SND_SOC_DAPM_MUX("IN1 Source Mux", SND_SOC_NOPM, 0, 0, + tad5x1x_dapm_in1_source_control), + SND_SOC_DAPM_MUX("IN2 Source Mux", SND_SOC_NOPM, 0, 0, + tad5x1x_dapm_in2_source_control), + SND_SOC_DAPM_PGA("ADC Power", TAC5X1X_PWR_CFG, 7, 0, NULL, 0), + SND_SOC_DAPM_AIF_OUT("AIF OUT", "ASI Capture", 0, SND_SOC_NOPM, 0, 0), +}; + +static const struct snd_soc_dapm_route taa5x1x_dapm_routes[] = { + /* ADC channel1 */ + {"IN1 Source Mux", "Analog", "AIN1"}, + {"IN2 Source Mux", "Analog", + "IN1 Source Mux"}, + + {"CH1_ADC_EN", NULL, "IN2 Source Mux"}, + {"ASI_TX_CH1_EN", "Capture Switch", "CH1_ADC_EN"}, + + {"ADC1 Config", "Differential", "ASI_TX_CH1_EN"}, + {"ADC1 Config", "Single-ended", "ASI_TX_CH1_EN"}, + {"ADC1 Config", "Single-ended mux INxP", + "ASI_TX_CH1_EN"}, + {"ADC1 Config", "Single-ended mux INxM", + "ASI_TX_CH1_EN"}, + + {"ADC1 Full-Scale", "2/10-VRMS", + "ADC1 Config"}, + {"ADC1 Full-Scale", "4/5-VRMS", + "ADC1 Config"}, + {"Mic Bias", NULL, "ADC1 Full-Scale"}, + +}; + +static const struct snd_soc_dapm_route tad5x1x_dapm_routes[] = { + /* Left Output */ + {"ASI_RX_CH1_EN", "Switch", "ASI IN1"}, + + {"OUT1x Source", "DAC + Analog Bypass Mix", "ASI_RX_CH1_EN"}, + {"OUT1x Source", "DAC -> OUTxP, INxP -> OUTxM", "ASI_RX_CH1_EN"}, + {"OUT1x Source", "INxM -> OUTxP, DAC -> OUTxM", "ASI_RX_CH1_EN"}, + + {"OUT1x Config", "Differential", "OUT1x Source"}, + // {"OUT1x Config", "Stereo Single-ended", "OUT1x Source"}, + {"OUT1x Config", "Mono Single-ended at OUTxP only", "OUT1x Source"}, + {"OUT1x Config", "Mono Single-ended at OUTxM only", "OUT1x Source"}, + {"OUT1x Config", "Pseudo differential with OUTxM as VCOM", + "OUT1x Source"}, + {"OUT1x Config", "Pseudo differential with OUTxM as external sensing", + "OUT1x Source"}, + {"OUT1x Config", "Pseudo differential with OUTxP as VCOM", + "OUT1x Source"}, + + {"OUT1x Driver", "Line-out", "OUT1x Config"}, + {"OUT1x Driver", "Headphone", "OUT1x Config"}, + + {"Left DAC Enable", NULL, "OUT1x Driver"}, + {"Left DAC Power", NULL, "Left DAC Enable"}, + + {"OUT1", NULL, "Left DAC Power"}, +}; + +static const struct snd_soc_dapm_route taa5x12_dapm_routes[] = { + /* ADC channel2 */ + {"CH2_ADC_EN", NULL, "AIN2"}, + + {"ASI_TX_CH2_EN", "Capture Switch", "CH2_ADC_EN"}, + + {"ADC2 Config", "Differential", "ASI_TX_CH2_EN"}, + {"ADC2 Config", "Single-ended", "ASI_TX_CH2_EN"}, + {"ADC2 Full-Scale", "2/10-VRMS", + "ADC2 Config"}, + {"ADC2 Full-Scale", "4/5-VRMS", + "ADC2 Config"}, + + {"Mic Bias", NULL, "ADC2 Full-Scale"}, +}; + +static const struct snd_soc_dapm_route tad5x12_dapm_routes[] = { + /* Right Output */ + {"ASI_RX_CH2_EN", "Switch", "ASI IN2"}, + + {"OUT2x Source", "DAC + Analog Bypass Mix", "ASI_RX_CH1_EN"}, + {"OUT2x Source", "DAC -> OUTxP, INxP -> OUTxM", "ASI_RX_CH1_EN"}, + {"OUT2x Source", "INxM -> OUTxP, DAC -> OUTxM", "ASI_RX_CH1_EN"}, + + {"OUT2x Config", "Differential", "OUT2x Source"}, + // {"OUT2x Config", "Stereo Single-ended", "OUT2x Source"}, + {"OUT2x Config", "Mono Single-ended at OUTxP only", "OUT2x Source"}, + {"OUT2x Config", "Mono Single-ended at OUTxM only", "OUT2x Source"}, + {"OUT2x Config", "Pseudo differential with OUTxM as VCOM", + "OUT2x Source"}, + {"OUT2x Config", "Pseudo differential with OUTxP as VCOM", + "OUT2x Source"}, + + {"OUT2x Driver", "Line-out", "OUT2x Config"}, + {"OUT2x Driver", "Headphone", "OUT2x Config"}, + + {"Right DAC Enable", NULL, "OUT2x Driver"}, + + {"Right DAC Power", NULL, "Right DAC Enable"}, + + {"OUT2", NULL, "Right DAC Power"}, +}; + +static const struct snd_soc_dapm_route tac5x1x_dapm_pdm_routes[] = { + /* PDM channel1 & Channel2 */ + {"IN1 Source Mux", "PDM", "DIN1"}, + {"IN2 Source Mux", "PDM", "DIN2"}, + + {"ASI_TX_CH1_EN", "Capture Switch", + "IN1 Source Mux"}, + {"ASI_TX_CH2_EN", "Capture Switch", + "IN2 Source Mux"}, + + {"CH1_PDM_EN", NULL, "ASI_TX_CH1_EN"}, + {"CH2_PDM_EN", NULL, "ASI_TX_CH2_EN"}, + + {"PDM ch1 & ch2 Datain Select", "GPIO1", "CH1_PDM_EN"}, + {"PDM ch1 & ch2 Datain Select", "GPIO2", "CH1_PDM_EN"}, + {"PDM ch1 & ch2 Datain Select", "GPI1", "CH1_PDM_EN"}, + + {"ADC Power", NULL, "PDM ch1 & ch2 Datain Select"}, + + /* PDM channel3 & Channel4 */ + {"ASI_TX_CH3_EN", "Capture Switch", "DIN3"}, + {"ASI_TX_CH4_EN", "Capture Switch", "DIN4"}, + + {"CH3_PDM_EN", NULL, "ASI_TX_CH3_EN"}, + {"CH4_PDM_EN", NULL, "ASI_TX_CH4_EN"}, + + {"PDM ch3 & ch4 Datain Select", "GPIO1", "CH3_PDM_EN"}, + {"PDM ch3 & ch4 Datain Select", "GPIO2", "CH3_PDM_EN"}, + {"PDM ch3 & ch4 Datain Select", "GPI1", "CH3_PDM_EN"}, + + {"ADC Power", NULL, "PDM ch3 & ch4 Datain Select"}, + {"AIF OUT", NULL, "ADC Power"}, +}; + +static const struct snd_soc_dapm_route tac5x1x_common_dapm_routes[] = { + {"ADC Power", NULL, "Mic Bias"}, + {"AIF OUT", NULL, "ADC Power"}, +}; + +static const struct reg_default tac5x1x_reg_defaults[] = { + {TAC5X1X_PGSEL, 0x00}, + {TAC5X1X_INT, 0x10}, + {TAC5X1X_ADCCH1C0, 0x04}, + {TAC5X1X_ADCCH2C0, 0x04}, + {TAC5X1X_OUT1CFG0, 0x20}, + {TAC5X1X_OUT2CFG0, 0x20}, + {TAC5X1X_CH_EN, 0x00}, + {TAC5X1X_PASITXCH1, 0x00}, + {TAC5X1X_PASITXCH2, 0x01}, + {TAC5X1X_PASIRXCH1, 0x00}, + {TAC5X1X_PASIRXCH2, 0x01}, + {}, +}; + +static s32 tac5x1x_pwr_ctrl(struct snd_soc_component *component, + bool power_state) +{ + struct tac5x1x_priv *tac5x1x = + snd_soc_component_get_drvdata(component); + s32 active_ctrl, ret; + s32 pwr_ctrl = 0; + + if (power_state) { + active_ctrl = TAC5X1X_VREF_SLEEP_ACTIVE_MASK; + snd_soc_component_update_bits(component, TAC5X1X_VREFCFG, + TAC5X1X_VREFCFG_MICBIAS_VAL_MASK, + tac5x1x->micbias_vg << 2); + snd_soc_component_update_bits(component, TAC5X1X_VREFCFG, + TAC5X1X_VREFCFG_VREF_FSCALE_MASK, + tac5x1x->vref_vg); + + if (tac5x1x->uad_en) + pwr_ctrl |= TAC5X1X_PWR_CFG_UAD_EN; + if (tac5x1x->vad_en) + pwr_ctrl |= TAC5X1X_PWR_CFG_VAD_EN; + if (tac5x1x->uag_en) + pwr_ctrl |= TAC5X1X_PWR_CFG_UAG_EN; + } else { + active_ctrl = 0x0; + } + + ret = snd_soc_component_update_bits(component, TAC5X1X_VREF, + TAC5X1X_VREF_SLEEP_EXIT_VREF_EN | + TAC5X1X_VREF_SLEEP_ACTIVE_MASK, active_ctrl); + if (ret < 0) { + dev_err(tac5x1x->dev, + "%s, device active or sleep failed!, ret %d/n", + __func__, ret); + return ret; + } + + ret = snd_soc_component_update_bits(component, TAC5X1X_PWR_CFG, + TAC5X1X_PWR_CFG_UAD_EN | TAC5X1X_PWR_CFG_UAG_EN | + TAC5X1X_PWR_CFG_VAD_EN, pwr_ctrl); + if (ret < 0) + dev_err(tac5x1x->dev, + "%s, Power control set failed!, ret %d/n", + __func__, ret); + return ret; +} + +static s32 tac5x1x_set_dai_fmt(struct snd_soc_dai *codec_dai, u32 fmt) +{ + struct snd_soc_component *component = codec_dai->component; + s32 iface_reg_1 = 0; + s32 iface_reg_2 = 0; + s32 iface_reg_3 = 0; + + dev_err(component->dev, "[tac5x1x] %s(), fmt=%d\n", __func__, fmt); + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBP_CFP: + iface_reg_1 |= TAC5X1X_PASI_MODE_MASK; + break; + case SND_SOC_DAIFMT_CBC_CFC: + break; + default: + dev_err(component->dev, + "%s: invalid DAI master/slave interface\n", + __func__); + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + iface_reg_2 |= TAC5X1X_PASI_FMT_I2S; + break; + case SND_SOC_DAIFMT_DSP_A: + iface_reg_2 |= TAC5X1X_PASI_FMT_TDM; + iface_reg_3 |= BIT(0); /* add offset 1 */ + break; + case SND_SOC_DAIFMT_DSP_B: + iface_reg_2 |= TAC5X1X_PASI_FMT_TDM; + break; + case SND_SOC_DAIFMT_LEFT_J: + iface_reg_2 |= TAC5X1X_PASI_FMT_LJ; + break; + default: + dev_err(component->dev, + "%s: invalid DAI interface format\n", __func__); + return -EINVAL; + } + + snd_soc_component_update_bits(component, TAC5X1X_CNTCLK2, + TAC5X1X_PASI_MODE_MASK, iface_reg_1); + snd_soc_component_update_bits(component, TAC5X1X_PASI0, + TAC5X1X_PASI_FMT_MASK, iface_reg_2); + snd_soc_component_update_bits(component, TAC5X1X_PASITX1, + TAC5X1X_PASITX_OFFSET_MASK, iface_reg_3); + snd_soc_component_update_bits(component, TAC5X1X_PASIRX0, + TAC5X1X_PASIRX_OFFSET_MASK, iface_reg_3); + return 0; +} + +static s32 tac5x1x_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_component *component = dai->component; + struct tac5x1x_priv *tac5x1x = + snd_soc_component_get_drvdata(component); + s32 sample_rate, word_length = 0; + + switch (params_rate(params)) { + case 24000: + sample_rate = 25; + break; + case 32000: + sample_rate = 23; + break; + case 44100: + case 48000: + sample_rate = 20; + break; + case 64000: + sample_rate = 18; + break; + case 96000: + sample_rate = 15; + break; + case 192000: + sample_rate = 10; + break; + default: + /* Auto detect sample rate */ + sample_rate = 0; + break; + } + + switch (params_physical_width(params)) { + case 16: + word_length |= TAC5X1X_WORD_LEN_16BITS; + break; + case 20: + word_length |= TAC5X1X_WORD_LEN_20BITS; + break; + case 24: + word_length |= TAC5X1X_WORD_LEN_24BITS; + break; + case 32: + word_length |= TAC5X1X_WORD_LEN_32BITS; + break; + default: + dev_err(tac5x1x->dev, "%s, set word length failed\n", + __func__); + return -EINVAL; + } + + snd_soc_component_update_bits(component, TAC5X1X_CLK0, TAC5X1X_PASI_SAMP_RATE_MASK, + sample_rate << 2); + snd_soc_component_update_bits(component, TAC5X1X_PASI0, + TAC5X1X_PASI_DATALEN_MASK, word_length); + + tac5x1x_pwr_ctrl(component, true); + return 0; +} + +static s32 tac5x1x_set_bias_level(struct snd_soc_component *component, + enum snd_soc_bias_level level) +{ + s32 ret; + struct tac5x1x_priv *tac5x1x = snd_soc_component_get_drvdata(component); + + switch (level) { + case SND_SOC_BIAS_ON: + ret = tac5x1x_pwr_ctrl(component, true); + if (ret < 0) + dev_err(tac5x1x->dev, "%s, power up failed!/n", __func__); + break; + case SND_SOC_BIAS_PREPARE: + break; + case SND_SOC_BIAS_STANDBY: + break; + case SND_SOC_BIAS_OFF: + ret = tac5x1x_pwr_ctrl(component, false); + if (ret < 0) + dev_err(tac5x1x->dev, "%s, power down failed!/n", __func__); + break; + } + + return ret; +} + +static const struct snd_soc_dai_ops tac5x1x_ops = { + .hw_params = tac5x1x_hw_params, + .set_fmt = tac5x1x_set_dai_fmt, + .no_capture_mute = 1, +}; + +static struct snd_soc_dai_driver tac5x1x_dai = { + .name = "tac5x1x-hifi", + .playback = { + .stream_name = "Playback", + .channels_min = 1, + .channels_max = 4, + .rates = TAC5X1X_RATES, + .formats = TAC5X1X_FORMATS,}, + .capture = { + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 4, + .rates = TAC5X1X_RATES, + .formats = TAC5X1X_FORMATS, + }, + .ops = &tac5x1x_ops, + .symmetric_rate = 1, +}; + +static struct snd_soc_dai_driver taa5x1x_dai = { + .name = "taa5x1x-hifi", + .capture = { + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 4, + .rates = TAC5X1X_RATES, + .formats = TAC5X1X_FORMATS, + }, + .ops = &tac5x1x_ops, + .symmetric_rate = 1, +}; + +static struct snd_soc_dai_driver tad5x1x_dai = { + .name = "tad5x1x-hifi", + .playback = { + .stream_name = "Playback", + .channels_min = 1, + .channels_max = 4, + .rates = TAC5X1X_RATES, + .formats = TAC5X1X_FORMATS, + }, + .capture = { + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 4, + .rates = TAC5X1X_RATES, + .formats = TAC5X1X_FORMATS, + }, + .ops = &tac5x1x_ops, + .symmetric_rate = 1, +}; + +static void tac5x1x_setup_gpios(struct snd_soc_component *component) +{ + struct tac5x1x_priv *tac5x1x = + snd_soc_component_get_drvdata(component); + s32 *gpio_drive = tac5x1x->gpio_setup->gpio_drive; + s32 *gpio_func = tac5x1x->gpio_setup->gpio_func; + + /* setup GPIO functions */ + /* GPIO1 */ + if (gpio_func[0] <= TAC5X1X_GPIO_DAISY_OUT) { + snd_soc_component_update_bits(component, TAC5X1X_GPIO1, TAC5X1X_GPIOX_CFG_MASK, + gpio_func[0] << 4); + snd_soc_component_update_bits(component, TAC5X1X_GPIO1, TAC5X1X_GPIOX_DRV_MASK, + gpio_drive[0]); + + if (gpio_func[0] == TAC5X1X_GPIO_GPI) + snd_soc_add_component_controls(component, tac5x1x_GPIO1_I, + ARRAY_SIZE(tac5x1x_GPIO1_I)); + else if (gpio_func[0] == TAC5X1X_GPIO_GPO) + snd_soc_add_component_controls(component, tac5x1x_GPIO1_O, + ARRAY_SIZE(tac5x1x_GPIO1_O)); + } + /* GPIO2 */ + if (gpio_func[1] <= TAC5X1X_GPIO_DAISY_OUT) { + snd_soc_component_update_bits(component, TAC5X1X_GPIO2, TAC5X1X_GPIOX_CFG_MASK, + gpio_func[1] << 4); + snd_soc_component_update_bits(component, TAC5X1X_GPIO2, TAC5X1X_GPIOX_DRV_MASK, + gpio_drive[1]); + + if (gpio_func[1] == TAC5X1X_GPIO_GPI) + snd_soc_add_component_controls(component, tac5x1x_GPIO2_I, + ARRAY_SIZE(tac5x1x_GPIO2_I)); + else if (gpio_func[1] == TAC5X1X_GPIO_GPO) + snd_soc_add_component_controls(component, tac5x1x_GPIO2_O, + ARRAY_SIZE(tac5x1x_GPIO2_O)); + } + /* GPO1 */ + if (gpio_func[2] <= TAC5X1X_GPIO_DAISY_OUT) { + snd_soc_component_update_bits(component, TAC5X1X_GPO1, TAC5X1X_GPIOX_CFG_MASK, + gpio_func[2] << 4); + snd_soc_component_update_bits(component, TAC5X1X_GPO1, TAC5X1X_GPIOX_DRV_MASK, + gpio_drive[2]); + + if (gpio_func[2] == TAC5X1X_GPIO_GPO) + snd_soc_add_component_controls(component, tac5x1x_GPO1, + ARRAY_SIZE(tac5x1x_GPO1)); + } + /* GPI1 */ + if (tac5x1x->gpio_setup->gpi1_func) { + snd_soc_component_update_bits(component, TAC5X1X_GPI1, TAC5X1X_GPI1_CFG_MASK, + TAC5X1X_GPI1_CFG_MASK); + snd_soc_add_component_controls(component, tac5x1x_GPI1, ARRAY_SIZE(tac5x1x_GPI1)); + } + /*GPA GPIO*/ + if (tac5x1x->gpio_setup->gpa_gpio) + snd_soc_component_update_bits(component, TAC5X1X_INTF5, TAC5X1X_GPA_CFG_MASK, + TAC5X1X_GPA_CFG_MASK); +} + +static s32 tac5x1x_reset(struct snd_soc_component *component) +{ + s32 ret, index; + + ret = snd_soc_component_write(component, TAC5X1X_RESET, 1); + if (ret < 0) + return ret; + /* Wait >= 10 ms after entering sleep mode. */ + usleep_range(10000, 100000); + + for (index = 0; index < ARRAY_SIZE(tac5x1x_reg_defaults); index++) { + ret = snd_soc_component_write(component, tac5x1x_reg_defaults[index].reg, + tac5x1x_reg_defaults[index].def); + if (ret < 0) + return ret; + } + return ret; +} + +static s32 tac5x1x_add_controls(struct snd_soc_component *component) +{ + struct tac5x1x_priv *tac5x1x = + snd_soc_component_get_drvdata(component); + s32 *gpio_func = tac5x1x->gpio_setup->gpio_func; + s32 ret; + + switch (tac5x1x->codec_type) { + case TAA5212: + ret = snd_soc_add_component_controls(component, tac5x12_impedance_controls, + ARRAY_SIZE(tac5x12_impedance_controls)); + if (ret) + return ret; + fallthrough; + case TAA5412: + ret = snd_soc_add_component_controls(component, tac5x12_tolerance_controls, + ARRAY_SIZE(tac5x12_tolerance_controls)); + if (ret) + return ret; + ret = snd_soc_add_component_controls(component, taa5x1x_ip_controls, + ARRAY_SIZE(taa5x1x_ip_controls)); + if (ret) + return ret; + break; + /* For Mono */ + case TAC5111: + case TAC5211: + ret = snd_soc_add_component_controls(component, tac5x11_controls, + ARRAY_SIZE(tac5x11_controls)); + if (ret) + return ret; + fallthrough; + case TAC5311: + case TAC5411: + ret = snd_soc_add_component_controls(component, tad5x1x_controls, + ARRAY_SIZE(tad5x1x_controls)); + if (ret) + return ret; + break; + /* For Stereo */ + case TAC5112: + case TAC5212: + ret = snd_soc_add_component_controls(component, tac5x12_impedance_controls, + ARRAY_SIZE(tac5x12_impedance_controls)); + if (ret) + return ret; + fallthrough; + case TAC5312: + case TAC5412: + ret = snd_soc_add_component_controls(component, tac5x12_tolerance_controls, + ARRAY_SIZE(tac5x12_tolerance_controls)); + if (ret) + return ret; + ret = snd_soc_add_component_controls(component, tad5x1x_controls, + ARRAY_SIZE(tad5x1x_controls)); + if (ret) + return ret; + + ret = snd_soc_add_component_controls(component, taa5x12_controls, + ARRAY_SIZE(taa5x12_controls)); + if (ret) + return ret; + + ret = snd_soc_add_component_controls(component, tad5x12_controls, + ARRAY_SIZE(tad5x12_controls)); + if (ret) + return ret; + break; + case TAD5212: + case TAD5112: + ret = snd_soc_add_component_controls(component, tad5x12_controls, + ARRAY_SIZE(tad5x12_controls)); + if (ret) + return ret; + + ret = snd_soc_add_component_controls(component, tad5x1x_pdm_controls, + ARRAY_SIZE(tad5x1x_pdm_controls)); + if (ret) + return ret; + break; + default: + break; + } + + /* If enabled PDM GPIO*/ + if (memchr(gpio_func, TAC5X1X_GPIO_PDMCLK, + sizeof(*gpio_func) / sizeof(gpio_func[0]))) { + ret = snd_soc_add_component_controls(component, tac5x1x_pdm_controls, + ARRAY_SIZE(tac5x1x_pdm_controls)); + if (ret) + return ret; + } + + return 0; +} + +static s32 tac5x1x_add_ip_diag_controls(struct snd_soc_component *component) +{ + struct tac5x1x_priv *tac5x1x = + snd_soc_component_get_drvdata(component); + s32 ret; + + switch (tac5x1x->codec_type) { + case TAA5212: + break; + case TAA5412: + case TAC5311: + case TAC5312: + case TAC5411: + case TAC5412: + if (tac5x1x->input_diag_config.in_ch_en) { + ret = snd_soc_add_component_controls(component, taa5x1x_ip_controls, + ARRAY_SIZE(taa5x1x_ip_controls)); + if (ret) + return ret; + snd_soc_component_update_bits(component, TAC5X1X_DIAG_CFG0, + TAC5X1X_IN_CH_DIAG_EN_MASK, + TAC5X1X_IN_CH_DIAG_EN_MASK); + } + if (tac5x1x->input_diag_config.out_ch_en) { + snd_soc_component_update_bits(component, TAC5X1X_DIAG_CFG0, + TAC5X1X_OUT1P_DIAG_EN_MASK, + TAC5X1X_OUT1P_DIAG_EN_MASK); + } + if (tac5x1x->input_diag_config.incl_se_inm) { + snd_soc_component_update_bits(component, TAC5X1X_DIAG_CFG0, + TAC5X1X_INCL_SE_INM_MASK, + TAC5X1X_INCL_SE_INM_MASK); + } + if (tac5x1x->input_diag_config.incl_ac_coup) { + snd_soc_component_update_bits(component, TAC5X1X_DIAG_CFG0, + TAC5X1X_INCL_AC_COUP_MASK, + TAC5X1X_INCL_AC_COUP_MASK); + } + snd_soc_component_update_bits(component, TAC5X1X_DIAG_CFG7, 0xff, + tac5x1x->micbias_threshold[0]); + snd_soc_component_update_bits(component, TAC5X1X_DIAG_CFG6, 0xff, + tac5x1x->micbias_threshold[1]); + ret = tac5x1x_register_interrupt(tac5x1x); + if (!ret) + dev_info(tac5x1x->dev, "Interrupt registration Done"); + fallthrough; + case TAC5111: + case TAC5112: + case TAC5211: + case TAC5212: + case TAD5112: + case TAD5212: + snd_soc_component_update_bits(component, TAC5X1X_DIAG_CFG9, 0xff, + tac5x1x->gpa_threshold[0]); + snd_soc_component_update_bits(component, TAC5X1X_DIAG_CFG8, 0xff, + tac5x1x->gpa_threshold[1]); + break; + default: + break; + }; + + return ret; +}; + +static s32 tac5x1x_add_widgets(struct snd_soc_component *component) +{ + struct tac5x1x_priv *tac5x1x = snd_soc_component_get_drvdata(component); + struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + s32 *gpio_func = tac5x1x->gpio_setup->gpio_func; + s32 ret; + + switch (tac5x1x->codec_type) { + case TAC5111: + case TAC5211: + case TAC5311: + case TAC5411: + ret = snd_soc_dapm_new_controls(dapm, tad5x1x_dapm_widgets, + ARRAY_SIZE(tad5x1x_dapm_widgets)); + if (ret) + return ret; + ret = snd_soc_dapm_add_routes(dapm, tad5x1x_dapm_routes, + ARRAY_SIZE(tad5x1x_dapm_routes)); + if (ret) + return ret; + break; + case TAC5112: + case TAC5212: + case TAC5312: + case TAC5412: + ret = snd_soc_dapm_new_controls(dapm, tad5x1x_dapm_widgets, + ARRAY_SIZE(tad5x1x_dapm_widgets)); + if (ret) + return ret; + ret = snd_soc_dapm_add_routes(dapm, tad5x1x_dapm_routes, + ARRAY_SIZE(tad5x1x_dapm_routes)); + if (ret) + return ret; + ret = snd_soc_dapm_new_controls(dapm, tad5x12_dapm_widgets, + ARRAY_SIZE(tad5x12_dapm_widgets)); + if (ret) + return ret; + ret = snd_soc_dapm_add_routes(dapm, tad5x12_dapm_routes, + ARRAY_SIZE(tad5x12_dapm_routes)); + if (ret) + return ret; + fallthrough; + case TAA5212: + case TAA5412: + ret = snd_soc_dapm_new_controls(dapm, taa5x12_dapm_widgets, + ARRAY_SIZE(taa5x12_dapm_widgets)); + if (ret) + return ret; + ret = snd_soc_dapm_add_routes(dapm, taa5x12_dapm_routes, + ARRAY_SIZE(taa5x12_dapm_routes)); + if (ret) + return ret; + break; + case TAD5212: + case TAD5112: + ret = snd_soc_dapm_new_controls(dapm, tad5xx_dapm_widgets, + ARRAY_SIZE(tad5xx_dapm_widgets)); + if (ret) + return ret; + + ret = snd_soc_dapm_new_controls(dapm, tad5x12_dapm_widgets, + ARRAY_SIZE(tad5x12_dapm_widgets)); + if (ret) + return ret; + ret = snd_soc_dapm_add_routes(dapm, tad5x12_dapm_routes, + ARRAY_SIZE(tad5x12_dapm_routes)); + if (ret) + return ret; + + break; + default: + break; + } + + if (!(tac5x1x->codec_type == TAD5212 || tac5x1x->codec_type == TAD5112)) { + ret = snd_soc_dapm_new_controls(dapm, tac5x1x_common_dapm_widgets, + ARRAY_SIZE(tac5x1x_common_dapm_widgets)); + if (ret) + return ret; + + ret = snd_soc_dapm_add_routes(dapm, tac5x1x_common_dapm_routes, + ARRAY_SIZE(tac5x1x_common_dapm_routes)); + if (ret) + return ret; + } else { + ret = snd_soc_dapm_new_controls(dapm, tad5x1x_common_dapm_widgets, + ARRAY_SIZE(tad5x1x_common_dapm_widgets)); + if (ret) + return ret; + } + /* If enabled PDM GPIO*/ + if (memchr(gpio_func, TAC5X1X_GPIO_PDMCLK, + sizeof(*gpio_func) / sizeof(gpio_func[0]))) { + ret = snd_soc_dapm_new_controls(dapm, tac5x1x_dapm_pdm_widgets, + ARRAY_SIZE(tac5x1x_dapm_pdm_widgets)); + if (ret) + return ret; + ret = snd_soc_dapm_add_routes(dapm, tac5x1x_dapm_pdm_routes, + ARRAY_SIZE(tac5x1x_dapm_pdm_routes)); + if (ret) + return ret; + } + return 0; +} + +static s32 tac5x1x_component_probe(struct snd_soc_component *component) +{ + s32 ret; + struct tac5x1x_priv *tac5x1x = snd_soc_component_get_drvdata(component); + + ret = tac5x1x_add_controls(component); + if (ret < 0) { + dev_err(tac5x1x->dev, "%s, add control failed\n", __func__); + return ret; + } + + ret = tac5x1x_add_widgets(component); + if (ret < 0) { + dev_err(tac5x1x->dev, "%s, device widget addition failed\n", __func__); + return ret; + } + + ret = tac5x1x_reset(component); + if (ret < 0) { + dev_err(tac5x1x->dev, "%s, device reset failed\n", __func__); + return ret; + } + + if (tac5x1x->gpio_setup) + tac5x1x_setup_gpios(component); + + ret = tac5x1x_add_ip_diag_controls(component); + if (ret < 0) { + dev_err(tac5x1x->dev, "%s, add Ip diag control failed\n", __func__); + return ret; + } + return ret; +} + +#ifdef CONFIG_PM +static s32 tac5x1x_soc_suspend(struct snd_soc_component *component) +{ + struct tac5x1x_priv *tac5x1x = + snd_soc_component_get_drvdata(component); + + regcache_cache_only(tac5x1x->regmap, true); + regcache_mark_dirty(tac5x1x->regmap); + + regulator_disable(tac5x1x->supply_avdd); + regulator_disable(tac5x1x->supply_iovdd); + + return 0; +} + +static s32 tac5x1x_soc_resume(struct snd_soc_component *component) +{ + struct tac5x1x_priv *tac5x1x = + snd_soc_component_get_drvdata(component); + s32 ret; + + regcache_cache_only(tac5x1x->regmap, false); + snd_soc_component_cache_sync(component); + + ret = regulator_enable(tac5x1x->supply_avdd); + if (ret) { + regulator_disable(tac5x1x->supply_avdd); + return ret; + } + + ret = regulator_enable(tac5x1x->supply_iovdd); + if (ret) { + regulator_disable(tac5x1x->supply_iovdd); + return ret; + } + return 0; +} +#else +#define tac5x1x_soc_suspend NULL +#define tac5x1x_soc_resume NULL +#endif /* CONFIG_PM */ + +static const struct snd_soc_component_driver soc_component_dev_tac5x1x = { + .probe = tac5x1x_component_probe, + .set_bias_level = tac5x1x_set_bias_level, + .suspend = tac5x1x_soc_suspend, + .resume = tac5x1x_soc_resume, + .controls = taa5x1x_controls, + .num_controls = ARRAY_SIZE(taa5x1x_controls), + .dapm_widgets = taa5x1x_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(taa5x1x_dapm_widgets), + .dapm_routes = taa5x1x_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(taa5x1x_dapm_routes), + .suspend_bias_off = 1, + .idle_bias_on = 1, + .use_pmdown_time = 1, + .endianness = 1, +}; + +static const struct snd_soc_component_driver soc_component_dev_taa5x1x = { + .probe = tac5x1x_component_probe, + .set_bias_level = tac5x1x_set_bias_level, + .suspend = tac5x1x_soc_suspend, + .resume = tac5x1x_soc_resume, + .controls = taa5x1x_controls, + .num_controls = ARRAY_SIZE(taa5x1x_controls), + .dapm_widgets = taa5x1x_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(taa5x1x_dapm_widgets), + .dapm_routes = taa5x1x_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(taa5x1x_dapm_routes), + .suspend_bias_off = 1, + .idle_bias_on = 1, + .use_pmdown_time = 1, + .endianness = 1, +}; + +static const struct snd_soc_component_driver soc_component_dev_tad5x1x = { + .probe = tac5x1x_component_probe, + .set_bias_level = tac5x1x_set_bias_level, + .suspend = tac5x1x_soc_suspend, + .resume = tac5x1x_soc_resume, + .controls = tad5x1x_controls, + .num_controls = ARRAY_SIZE(tad5x1x_controls), + .dapm_widgets = tad5x1x_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(tad5x1x_dapm_widgets), + .dapm_routes = tad5x1x_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(tad5x1x_dapm_routes), + .suspend_bias_off = 1, + .idle_bias_on = 1, + .use_pmdown_time = 1, + .endianness = 1, +}; + +static s32 tac5x1x_parse_dt(struct tac5x1x_priv *tac5x1x, + struct device_node *np) +{ + struct tac5x1x_input_diag_config input_config; + struct tac5x1x_setup_gpio *tac5x1x_setup; + s32 micbias_value = TAC5X1X_MICBIAS_VREF; + s32 vref_value = TAC5X1X_VERF_2_5V; + s32 ret; + + tac5x1x_setup = devm_kzalloc(tac5x1x->dev, sizeof(*tac5x1x_setup), + GFP_KERNEL); + if (!tac5x1x_setup) + return -ENOMEM; + + ret = fwnode_property_read_u32(tac5x1x->dev->fwnode, "ti,vref", &vref_value); + if (ret) { + dev_err(tac5x1x->dev, "Fail to get verf E:%d\n", ret); + goto out; + } + ret = fwnode_property_read_u32(tac5x1x->dev->fwnode, "ti,micbias-vg", &micbias_value); + if (ret) { + dev_err(tac5x1x->dev, "Fail to get micbias-vg E:%d\n", ret); + goto out; + } + + if (micbias_value == TAC5X1X_MICBIAS_AVDD) { + tac5x1x->micbias_vg = micbias_value; + tac5x1x->vref_vg = TAC5X1X_VERF_2_75V; + tac5x1x->micbias_en = true; + } else { + switch (vref_value) { + case TAC5X1X_VERF_2_75V: + case TAC5X1X_VERF_2_5V: + switch (micbias_value) { + case TAC5X1X_MICBIAS_VREF: + case TAC5X1X_MICBIAS_0_5VREF: + tac5x1x->micbias_vg = micbias_value; + break; + default: + dev_err(tac5x1x->dev, "Bad tac5x1x-micbias-vg value %d\n", + micbias_value); + tac5x1x->micbias_vg = TAC5X1X_MICBIAS_AVDD; + break; + } + tac5x1x->vref_vg = vref_value; + tac5x1x->micbias_en = true; + break; + case TAC5X1X_VERF_1_375V: + if (micbias_value == TAC5X1X_MICBIAS_VREF) { + tac5x1x->micbias_vg = micbias_value; + } else { + dev_err(tac5x1x->dev, "Bad tac5x1x-micbias-vg value %d\n", + micbias_value); + tac5x1x->micbias_vg = TAC5X1X_MICBIAS_AVDD; + } + tac5x1x->micbias_en = true; + tac5x1x->vref_vg = vref_value; + break; + default: + dev_err(tac5x1x->dev, "Bad tac5x1x-vref-vg value %d\n", vref_value); + tac5x1x->vref_vg = TAC5X1X_VERF_2_5V; + tac5x1x->micbias_vg = TAC5X1X_MICBIAS_AVDD; + tac5x1x->micbias_en = true; + break; + } + } + + if (fwnode_property_read_u32(tac5x1x->dev->fwnode, "ti,gpi1-func", + &tac5x1x_setup->gpi1_func)) + dev_err(tac5x1x->dev, "%s, Fail to get gpi1-func value\n", __func__); + + if (fwnode_property_read_u32(tac5x1x->dev->fwnode, "ti,gpa-gpio", + &tac5x1x_setup->gpa_gpio)) + dev_err(tac5x1x->dev, "%s, Fail to get gpa-gpio value\n", __func__); + + if (fwnode_property_read_u32_array(tac5x1x->dev->fwnode, "ti,gpios-func", + tac5x1x_setup->gpio_func, 3)) + dev_err(tac5x1x->dev, "%s, Fail to get gpios-func value\n", __func__); + if (fwnode_property_read_u32_array(tac5x1x->dev->fwnode, "ti,gpios-drive", + tac5x1x_setup->gpio_drive, 3)) + dev_err(tac5x1x->dev, "%s, Fail to get gpios-drive value\n", __func__); + + tac5x1x->gpa_threshold[0] = TAC5X1X_GPA_LOW_THRESHOLD; + tac5x1x->gpa_threshold[1] = TAC5X1X_GPA_HIGH_THRESHOLD; + if (fwnode_property_read_u32_array(tac5x1x->dev->fwnode, "ti,gpa-threshold", + tac5x1x->gpa_threshold, 2)) + dev_err(tac5x1x->dev, "%s, Fail to get ti,gpa-threshold value\n", __func__); + + tac5x1x->gpio_setup = tac5x1x_setup; + + switch (tac5x1x->codec_type) { + case TAA5212: + case TAC5111: + case TAC5112: + case TAC5211: + case TAC5212: + case TAD5112: + case TAD5212: + break; + case TAA5412: + case TAC5411: + case TAC5412: + case TAC5311: + case TAC5312: + tac5x1x->input_diag_config.in_ch_en = 0; + if (fwnode_property_read_u32(tac5x1x->dev->fwnode, "ti,in-ch-en", + &input_config.in_ch_en)) + dev_err(tac5x1x->dev, "%s, Fail to get ti,in-ch-en value\n", __func__); + tac5x1x->input_diag_config.out_ch_en = 0; + if (fwnode_property_read_u32(tac5x1x->dev->fwnode, + "ti,out-ch-en", &input_config.in_ch_en)) + dev_err(tac5x1x->dev, "%s, Fail to get ti,out-ch-en value\n", __func__); + tac5x1x->input_diag_config.incl_se_inm = 0; + if (fwnode_property_read_u32(tac5x1x->dev->fwnode, "ti,incl-se-inm", + &input_config.incl_se_inm)) + dev_err(tac5x1x->dev, "%s, Fail to get ti,incl-se-inm value\n", __func__); + tac5x1x->input_diag_config.incl_ac_coup = 0; + if (fwnode_property_read_u32(tac5x1x->dev->fwnode, + "ti,incl-ac-coup", &input_config.incl_ac_coup)) + dev_err(tac5x1x->dev, "%s, Fail to get ti,incl-ac-coup value\n", __func__); + tac5x1x->input_diag_config = input_config; + + tac5x1x->micbias_threshold[0] = TAC5X1X_MICBIAS_LOW_THRESHOLD; + tac5x1x->micbias_threshold[1] = + TAC5X1X_MICBIAS_HIGH_THRESHOLD; + if (fwnode_property_read_u32_array(tac5x1x->dev->fwnode, "ti,micbias-threshold", + tac5x1x->micbias_threshold, 2)) + dev_err(tac5x1x->dev, "%s, Fail to get ti,micbias-threshold value\n", + __func__); + break; + } +out: + return ret; +} + +static void tac5x1x_disable_regulators(struct tac5x1x_priv *tac5x1x) +{ + if (!IS_ERR(tac5x1x->supply_iovdd)) + regulator_disable(tac5x1x->supply_iovdd); + + if (!IS_ERR(tac5x1x->supply_avdd)) + regulator_disable(tac5x1x->supply_avdd); +} + +static s32 tac5x1x_setup_regulators(struct device *dev, + struct tac5x1x_priv *tac5x1x) +{ + s32 ret; + + tac5x1x->supply_iovdd = devm_regulator_get(dev, "iovdd"); + tac5x1x->supply_avdd = devm_regulator_get(dev, "avdd"); + + /* Check if the regulator requirements are fulfilled */ + if (IS_ERR(tac5x1x->supply_iovdd)) { + dev_err(dev, "Missing supply 'iovdd'\n"); + return PTR_ERR(tac5x1x->supply_iovdd); + } + + if (IS_ERR(tac5x1x->supply_avdd)) { + dev_err(dev, "Missing supply 'avdd'\n"); + return PTR_ERR(tac5x1x->supply_avdd); + } + + ret = regulator_enable(tac5x1x->supply_iovdd); + if (ret) { + dev_err(dev, "Failed to enable regulator iovdd\n"); + regulator_disable(tac5x1x->supply_iovdd); + return ret; + } + + ret = regulator_enable(tac5x1x->supply_avdd); + if (ret) { + dev_err(dev, "Failed to enable regulator avdd\n"); + regulator_disable(tac5x1x->supply_avdd); + return ret; + } + + return 0; +} + +s32 tac5x1x_probe(struct device *dev, struct regmap *regmap, + enum tac5x1x_type type) +{ + struct device_node *np = dev->of_node; + struct tac5x1x_priv *tac5x1x; + s32 ret; + + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + tac5x1x = devm_kzalloc(dev, sizeof(struct tac5x1x_priv), + GFP_KERNEL); + if (!tac5x1x) + return -ENOMEM; + + tac5x1x->dev = dev; + tac5x1x->codec_type = type; + tac5x1x->regmap = regmap; + tac5x1x->ndev = 1; + + dev_set_drvdata(dev, tac5x1x); + if (np) { + ret = tac5x1x_parse_dt(tac5x1x, np); + if (ret) { + dev_err(dev, "Failed to parse DT node\n"); + return ret; + } + } else { + dev_err(dev, "%s: Fail to get device node\n", __func__); + } + + ret = tac5x1x_setup_regulators(dev, tac5x1x); + if (ret) { + dev_err(dev, "Failed to setup regulators\n"); + return ret; + } + + switch (tac5x1x->codec_type) { + case TAA5212: + case TAA5412: + ret = devm_snd_soc_register_component(dev, + &soc_component_dev_taa5x1x, &taa5x1x_dai, 1); + if (ret) { + dev_err(dev, "Failed to register component\n"); + goto err_disable_regulators; + } + break; + case TAC5111: + case TAC5112: + case TAC5211: + case TAC5212: + case TAC5311: + case TAC5312: + case TAC5411: + case TAC5412: + ret = devm_snd_soc_register_component(dev, + &soc_component_dev_tac5x1x, &tac5x1x_dai, 1); + if (ret) { + dev_err(dev, "Failed to register component\n"); + goto err_disable_regulators; + } + break; + case TAD5112: + case TAD5212: + ret = devm_snd_soc_register_component(dev, + &soc_component_dev_tad5x1x, &tad5x1x_dai, 1); + if (ret) { + dev_err(dev, "Failed to register component\n"); + goto err_disable_regulators; + } + break; + } + return 0; + +err_disable_regulators: + tac5x1x_disable_regulators(tac5x1x); + + return ret; +} +EXPORT_SYMBOL(tac5x1x_probe); + +s32 tac5x1x_remove(struct device *dev) +{ + struct tac5x1x_priv *tac5x1x = dev_get_drvdata(dev); + + tac5x1x_disable_regulators(tac5x1x); + if (tac5x1x->irq_work_func) { + dev_info(tac5x1x->dev, "Cancelled IRQ\n"); + free_irq(tac5x1x->irqinfo.irq, tac5x1x); + mutex_destroy(&tac5x1x->dev_lock); + } + return 0; +} +EXPORT_SYMBOL(tac5x1x_remove); + +const struct of_device_id tac5x1x_of_match[] = { + { .compatible = "ti,taa5212", .data = (void *)TAA5212 }, + { .compatible = "ti,taa5412", .data = (void *)TAA5412 }, + { .compatible = "ti,tac5111", .data = (void *)TAC5111 }, + { .compatible = "ti,tac5112", .data = (void *)TAC5112 }, + { .compatible = "ti,tac5211", .data = (void *)TAC5211 }, + { .compatible = "ti,tac5212", .data = (void *)TAC5212 }, + { .compatible = "ti,tac5311", .data = (void *)TAC5311 }, + { .compatible = "ti,tac5312", .data = (void *)TAC5312 }, + { .compatible = "ti,tac5411", .data = (void *)TAC5411 }, + { .compatible = "ti,tac5412", .data = (void *)TAC5412 }, + { .compatible = "ti,tad5112", .data = (void *)TAD5112 }, + { .compatible = "ti,tad5212", .data = (void *)TAD5212 }, + {} +}; +EXPORT_SYMBOL_GPL(tac5x1x_of_match); +MODULE_DEVICE_TABLE(of, tac5x1x_of_match); + +MODULE_DESCRIPTION("ASoC tac5x1x codec driver"); +MODULE_AUTHOR("Texas Instruments"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/tac5x1x.h b/sound/soc/codecs/tac5x1x.h new file mode 100644 index 000000000000..d3f2d5b4769c --- /dev/null +++ b/sound/soc/codecs/tac5x1x.h @@ -0,0 +1,302 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Audio Codec Driver Supporting Devices + * TAA5X1X, TAC5X1X, TAD5X1X + * + * Copyright (C) 2024-2025 Texas Instruments Incorporated - https://www.ti.com + * + * Author: Kevin Lu kevin-lu@ti.com + * Author: Kokila Karuppusamy kokila.karuppusamy@ti.com + * Author: Niranjan H Y niranjan.hy@ti.com + */ + +#ifndef _TAC5X1X_H +#define _TAC5X1X_H + +#define TAC5X1X_RATES SNDRV_PCM_RATE_8000_192000 +#define TAC5X1X_FORMATS (SNDRV_PCM_FMTBIT_S16_LE \ + | SNDRV_PCM_FMTBIT_S20_3LE \ + | SNDRV_PCM_FMTBIT_S24_LE \ + | SNDRV_PCM_FMTBIT_S24_3LE \ + | SNDRV_PCM_FMTBIT_S32_LE) + +/*PAGE Control Register (available in page0 of each book) */ +#define TAC_PAGE_SELECT 0x00 +#define TAC_PAGE_ID(reg) ((reg) / 128) +#define TAC_PAGE_REG(reg) ((reg) % 128) +#define TAC5X1X_REG(page, reg) (((page) * 128) + (reg)) + +#define TAC_PAGE1_SELECT 0x01 +#define TAC5X1X_PGSEL TAC5X1X_REG(0, 0x0) + +#define TAC5X1X_RESET TAC5X1X_REG(0, 0x1) +#define TAC5X1X_VREF TAC5X1X_REG(0, 0x2) +#define TAC5X1X_VDDSTS TAC5X1X_REG(0, 0x3) +#define TAC5X1X_MISC TAC5X1X_REG(0, 0x4) +#define TAC5X1X_MISC1 TAC5X1X_REG(0, 0x5) +#define TAC5X1X_DACA0 TAC5X1X_REG(0, 0x6) +#define TAC5X1X_MISC0 TAC5X1X_REG(0, 0x7) +#define TAC5X1X_GPIO1 TAC5X1X_REG(0, 0xa) +#define TAC5X1X_GPIO2 TAC5X1X_REG(0, 0xb) +#define TAC5X1X_GPO1 TAC5X1X_REG(0, 0xc) +#define TAC5X1X_GPI1 TAC5X1X_REG(0, 0xd) +#define TAC5X1X_GPIOVAL TAC5X1X_REG(0, 0xe) +#define TAC5X1X_INTF0 TAC5X1X_REG(0, 0xf) +#define TAC5X1X_INTF1 TAC5X1X_REG(0, 0x10) +#define TAC5X1X_INTF2 TAC5X1X_REG(0, 0x11) +#define TAC5X1X_INTF3 TAC5X1X_REG(0, 0x12) +#define TAC5X1X_INTF4 TAC5X1X_REG(0, 0x13) +#define TAC5X1X_INTF5 TAC5X1X_REG(0, 0x14) +#define TAC5X1X_INTF6 TAC5X1X_REG(0, 0x15) +#define TAC5X1X_ASI0 TAC5X1X_REG(0, 0x18) +#define TAC5X1X_ASI1 TAC5X1X_REG(0, 0x19) +#define TAC5X1X_PASI0 TAC5X1X_REG(0, 0x1a) +#define TAC5X1X_PASITX0 TAC5X1X_REG(0, 0x1b) +#define TAC5X1X_PASITX1 TAC5X1X_REG(0, 0x1c) +#define TAC5X1X_PASITX2 TAC5X1X_REG(0, 0x1d) +#define TAC5X1X_PASITXCH1 TAC5X1X_REG(0, 0x1e) +#define TAC5X1X_PASITXCH2 TAC5X1X_REG(0, 0x1f) +#define TAC5X1X_PASITXCH3 TAC5X1X_REG(0, 0x20) +#define TAC5X1X_PASITXCH4 TAC5X1X_REG(0, 0x21) +#define TAC5X1X_PASITXCH5 TAC5X1X_REG(0, 0x22) +#define TAC5X1X_PASITXCH6 TAC5X1X_REG(0, 0x23) +#define TAC5X1X_PASITXCH7 TAC5X1X_REG(0, 0x24) +#define TAC5X1X_PASITXCH8 TAC5X1X_REG(0, 0x25) +#define TAC5X1X_PASIRX0 TAC5X1X_REG(0, 0x26) +#define TAC5X1X_PASIRX1 TAC5X1X_REG(0, 0x27) +#define TAC5X1X_PASIRXCH1 TAC5X1X_REG(0, 0x28) +#define TAC5X1X_PASIRXCH2 TAC5X1X_REG(0, 0x29) +#define TAC5X1X_PASIRXCH3 TAC5X1X_REG(0, 0x2a) +#define TAC5X1X_PASIRXCH4 TAC5X1X_REG(0, 0x2b) +#define TAC5X1X_PASIRXCH5 TAC5X1X_REG(0, 0x2c) +#define TAC5X1X_PASIRXCH6 TAC5X1X_REG(0, 0x2d) +#define TAC5X1X_PASIRXCH7 TAC5X1X_REG(0, 0x2e) +#define TAC5X1X_PASIRXCH8 TAC5X1X_REG(0, 0x2f) +#define TAC5X1X_CLK0 TAC5X1X_REG(0, 0x32) +#define TAC5X1X_CLK1 TAC5X1X_REG(0, 0x33) +#define TAC5X1X_CLK2 TAC5X1X_REG(0, 0x34) +#define TAC5X1X_CNTCLK0 TAC5X1X_REG(0, 0x35) +#define TAC5X1X_CNTCLK1 TAC5X1X_REG(0, 0x36) +#define TAC5X1X_CNTCLK2 TAC5X1X_REG(0, 0x37) +#define TAC5X1X_CNTCLK3 TAC5X1X_REG(0, 0x38) +#define TAC5X1X_CNTCLK4 TAC5X1X_REG(0, 0x39) +#define TAC5X1X_CNTCLK5 TAC5X1X_REG(0, 0x3a) +#define TAC5X1X_CNTCLK6 TAC5X1X_REG(0, 0x3b) +#define TAC5X1X_CLKERRSTS0 TAC5X1X_REG(0, 0x3c) +#define TAC5X1X_CLKERRSTS1 TAC5X1X_REG(0, 0x3d) +#define TAC5X1X_CLKDETSTS0 TAC5X1X_REG(0, 0x3e) +#define TAC5X1X_CLKDETSTS1 TAC5X1X_REG(0, 0x3f) +#define TAC5X1X_CLKDETSTS2 TAC5X1X_REG(0, 0x40) +#define TAC5X1X_CLKDETSTS3 TAC5X1X_REG(0, 0x41) +#define TAC5X1X_INT TAC5X1X_REG(0, 0x42) +#define TAC5X1X_DAC_FLT TAC5X1X_REG(0, 0x43) +#define TAC5X1X_ADCDACMISC TAC5X1X_REG(0, 0x4b) +#define TAC5X1X_IADC TAC5X1X_REG(0, 0x4c) +#define TAC5X1X_VREFCFG TAC5X1X_REG(0, 0x4d) +#define TAC5X1X_PWRTUNE0 TAC5X1X_REG(0, 0x4e) +#define TAC5X1X_PWRTUNE1 TAC5X1X_REG(0, 0x4f) +#define TAC5X1X_ADCCH1C0 TAC5X1X_REG(0, 0x50) +#define TAC5X1X_ADCCH TAC5X1X_REG(0, 0x51) +#define TAC5X1X_ADCCH1C2 TAC5X1X_REG(0, 0x52) +#define TAC5X1X_ADCCH1C3 TAC5X1X_REG(0, 0x53) +#define TAC5X1X_ADCCH1C4 TAC5X1X_REG(0, 0x54) +#define TAC5X1X_ADCCH2C0 TAC5X1X_REG(0, 0x55) +#define TAC5X1X_ADCCH2C2 TAC5X1X_REG(0, 0x57) +#define TAC5X1X_ADCCH2C3 TAC5X1X_REG(0, 0x58) +#define TAC5X1X_ADCCH2C4 TAC5X1X_REG(0, 0x59) +#define TAC5X1X_ADCCH3C0 TAC5X1X_REG(0, 0x5a) +#define TAC5X1X_ADCCH3C2 TAC5X1X_REG(0, 0x5b) +#define TAC5X1X_ADCCH3C3 TAC5X1X_REG(0, 0x5c) +#define TAC5X1X_ADCCH3C4 TAC5X1X_REG(0, 0x5d) +#define TAC5X1X_ADCCH4C0 TAC5X1X_REG(0, 0x5e) +#define TAC5X1X_ADCCH4C2 TAC5X1X_REG(0, 0x5f) +#define TAC5X1X_ADCCH4C3 TAC5X1X_REG(0, 0x60) +#define TAC5X1X_ADCCH4C4 TAC5X1X_REG(0, 0x61) +#define TAC5X1X_ADCCFG1 TAC5X1X_REG(0, 0x62) +#define TAC5X1X_OUT1CFG0 TAC5X1X_REG(0, 0x64) +#define TAC5X1X_OUT1CFG1 TAC5X1X_REG(0, 0x65) +#define TAC5X1X_OUT1CFG2 TAC5X1X_REG(0, 0x66) +#define TAC5X1X_DACCH1A0 TAC5X1X_REG(0, 0x67) +#define TAC5X1X_DACCH1A1 TAC5X1X_REG(0, 0x68) +#define TAC5X1X_DACCH1B0 TAC5X1X_REG(0, 0x69) +#define TAC5X1X_DACCH1B1 TAC5X1X_REG(0, 0x6a) +#define TAC5X1X_OUT2CFG0 TAC5X1X_REG(0, 0x6b) +#define TAC5X1X_OUT2CFG1 TAC5X1X_REG(0, 0x6c) +#define TAC5X1X_OUT2CFG2 TAC5X1X_REG(0, 0x6d) +#define TAC5X1X_DACCH2A0 TAC5X1X_REG(0, 0x6e) +#define TAC5X1X_DACCH2A1 TAC5X1X_REG(0, 0x6f) +#define TAC5X1X_DACCH2B0 TAC5X1X_REG(0, 0x70) +#define TAC5X1X_DACCH2B1 TAC5X1X_REG(0, 0x71) +#define TAC5X1X_DSP0 TAC5X1X_REG(0, 0x72) +#define TAC5X1X_DSP1 TAC5X1X_REG(0, 0x73) +#define TAC5X1X_CH_EN TAC5X1X_REG(0, 0x76) +#define TAC5X1X_DYN_PUPD TAC5X1X_REG(0, 0x77) +#define TAC5X1X_PWR_CFG TAC5X1X_REG(0, 0x78) +#define TAC5X1X_DEVSTS0 TAC5X1X_REG(0, 0x79) +#define TAC5X1X_DEVSTS1 TAC5X1X_REG(0, 0x7a) + +#define TAC5X1X_CLKCFG0 TAC5X1X_REG(1, 0xd) +#define TAC5X1X_MICBIAS1 TAC5X1X_REG(1, 0x16) +#define TAC5X1X_AGC_DRC TAC5X1X_REG(1, 0x24) +#define TAC5X1X_PLIM TAC5X1X_REG(1, 0x2b) +#define TAC5X1X_MIXER TAC5X1X_REG(1, 0x2c) + +#define TAC5X1X_DIAG_CFG0 TAC5X1X_REG(1, 0x46) +#define TAC5X1X_DIAG_CFG1 TAC5X1X_REG(1, 0x47) +#define TAC5X1X_DIAG_CFG2 TAC5X1X_REG(1, 0x48) +#define TAC5X1X_DIAG_CFG8 TAC5X1X_REG(1, 0x4e) +#define TAC5X1X_DIAG_CFG9 TAC5X1X_REG(1, 0x4b) +#define TAC5X1X_DIAG_CFG6 TAC5X1X_REG(1, 0x4c) +#define TAC5X1X_DIAG_CFG7 TAC5X1X_REG(1, 0x4d) +/* Bits, masks, and shifts */ + +#define TAC5X1X_REG_INT_LTCH0 TAC5X1X_REG(0x1, 0x34) +#define TAC5X1X_REG_CHX_LTCH TAC5X1X_REG(0x1, 0x35) +#define TAC5X1X_REG_IN_CH1_LTCH TAC5X1X_REG(0x1, 0x36) +#define TAC5X1X_REG_IN_CH2_LTCH TAC5X1X_REG(0x1, 0x37) +#define TAC5X1X_REG_OUT_CH1_LTCH TAC5X1X_REG(0x1, 0x38) +#define TAC5X1X_REG_OUT_CH2_LTCH TAC5X1X_REG(0x1, 0x39) +#define TAC5X1X_REG_INT_LTCH1 TAC5X1X_REG(0x1, 0x3A) +#define TAC5X1X_REG_INT_LTCH2 TAC5X1X_REG(0x1, 0x3B) + +/* TAC5X1X_CH_EN */ + +#define TAC5X1X_CH_EN_ADC_MASK GENMASK(7, 4) +#define TAC5X1X_CH_EN_ADC_CH1 BIT(7) +#define TAC5X1X_CH_EN_ADC_CH2 BIT(6) +#define TAC5X1X_CH_EN_ADC_CH3 BIT(5) +#define TAC5X1X_CH_EN_ADC_CH4 BIT(4) + +#define TAC5X1X_CH_EN_DAC_MASK GENMASK(3, 0) +#define TAC5X1X_CH_EN_DAC_CH1 BIT(3) +#define TAC5X1X_CH_EN_DAC_CH2 BIT(2) +#define TAC5X1X_CH_EN_DAC_CH3 BIT(1) +#define TAC5X1X_CH_EN_DAC_CH4 BIT(0) + +/* TAC5X1X_GPIOVAL */ +#define TAC5X1X_GPIO1_VAL BIT(7) +#define TAC5X1X_GPIO2_VAL BIT(6) +#define TAC5X1X_GPO1_VAL BIT(5) +#define TAC5X1X_GPIO1_MON BIT(3) +#define TAC5X1X_GPIO2_MON BIT(2) +#define TAC5X1X_GPI1_MON BIT(1) + +/* TAC5X1X_DIAG_CFG0 */ +#define TAC5X1X_IN_CH_DIAG_EN_MASK 0xc0 +#define TAC5X1X_INCL_SE_INM_MASK 0x20 +#define TAC5X1X_INCL_AC_COUP_MASK 0x10 +#define TAC5X1X_OUT1P_DIAG_EN_MASK 0x0f +#define TAC5X1X_MICBIAS_LOW_THRESHOLD 0x48 +#define TAC5X1X_MICBIAS_HIGH_THRESHOLD 0xa2 +#define TAC5X1X_GPA_LOW_THRESHOLD 0x4b +#define TAC5X1X_GPA_HIGH_THRESHOLD 0xba + +/* TAC5X1X_PASI */ +#define TAC5X1X_PASI_SAMP_RATE_MASK GENMASK(7, 2) +#define TAC5X1X_PASI_FMT_MASK GENMASK(7, 6) +#define TAC5X1X_PASI_FMT_TDM 0x00 +#define TAC5X1X_PASI_FMT_I2S 0x40 +#define TAC5X1X_PASI_FMT_LJ 0x80 + +#define TAC5X1X_PASI_DATALEN_MASK GENMASK(5, 4) +#define TAC5X1X_WORD_LEN_16BITS 0x00 +#define TAC5X1X_WORD_LEN_20BITS 0x10 +#define TAC5X1X_WORD_LEN_24BITS 0x20 +#define TAC5X1X_WORD_LEN_32BITS 0x30 + +/* TAC5X1X_CNTCLK2 */ +#define TAC5X1X_PASI_MODE_MASK 0x10 +#define TAC5X1X_SASI_MODE_MASK 0x08 +#define TAC5X1X_ASI_RATE_MASK 0x01 + +#define TAC5X1X_PASI_RATE_48000 0x00 +#define TAC5X1X_PASI_RATE_44100 0x01 + +/* TAC5X1X_PASITX0 */ +#define TAC5X1X_PASITX_OFFSET_MASK 0x1f + +/* TAC5X1X_PASIRX0 */ +#define TAC5X1X_PASIRX_OFFSET_MASK 0x1f + +/* TAC5X1X_VREF */ +#define TAC5X1X_VREF_SLEEP_EXIT_VREF_EN 0x80 +#define TAC5X1X_VREF_SLEEP_ACTIVE_MASK 0x01 + +/* TAC5X1X_PWRCFG */ +#define TAC5X1X_PWR_CFG_ADC_PDZ BIT(7) +#define TAC5X1X_PWR_CFG_DAC_PDZ BIT(6) +#define TAC5X1X_PWR_CFG_MICBIAS BIT(5) +#define TAC5X1X_PWR_CFG_UAD_EN BIT(3) +#define TAC5X1X_PWR_CFG_VAD_EN BIT(2) +#define TAC5X1X_PWR_CFG_UAG_EN BIT(1) + +/* TAC5X1X_GPIOx */ +#define TAC5X1X_GPIO1_DEFAULT_VAL 0x32 +#define TAC5X1X_GPIO2_DEFAULT_VAL 0x00 +#define TAC5X1X_GPI1_DEFAULT_VAL 0x00 +#define TAC5X1X_GPO1_DEFAULT_VAL 0x00 + +#define TAC5X1X_GPIOX_CFG_MASK 0xf0 +#define TAC5X1X_GPIOX_DRV_MASK 0x07 + +#define TAC5X1X_GPIO_DISABLE 0 +#define TAC5X1X_GPIO_GPI 1 +#define TAC5X1X_GPIO_GPO 2 +#define TAC5X1X_GPIO_IRQ 3 +#define TAC5X1X_GPIO_PDMCLK 4 +#define TAC5X1X_GPIO_P_DOUT 5 +#define TAC5X1X_GPIO_P_DOUT2 6 +#define TAC5X1X_GPIO_S_DOUT 7 +#define TAC5X1X_GPIO_S_DOUT2 8 +#define TAC5X1X_GPIO_S_BCLK 9 +#define TAC5X1X_GPIO_S_FSYNC 10 +#define TAC5X1X_GPIO_CLKOUT 11 +#define TAC5X1X_GPIO_DOUT_MUX 12 +#define TAC5X1X_GPIO_DAISY_OUT 13 + +#define TAC5X1X_GPIO_DRV_HIZ 0 +#define TAC5X1X_GPIO_DRV_ALAH 1 +#define TAC5X1X_GPIO_DRV_ALWH 2 +#define TAC5X1X_GPIO_DRV_ALHIZ 3 +#define TAC5X1X_GPIO_DRV_WLAH 4 +#define TAC5X1X_GPIO_DRV_HIZAH 5 + +/* TAC5X1X_GPI1 */ +#define TAC5X1X_GPI1_CFG_MASK BIT(1) +#define TAC5X1X_GPA_CFG_MASK BIT(0) + +/* TAC5X1X_VREFCFG */ +#define TAC5X1X_VREFCFG_MICBIAS_VAL_MASK GENMASK(3, 2) +#define TAC5X1X_VREFCFG_VREF_FSCALE_MASK GENMASK(1, 0) + +#define TAC5X1X_MICBIAS_VREF 0 +#define TAC5X1X_MICBIAS_0_5VREF 1 +#define TAC5X1X_MICBIAS_AVDD 3 + +#define TAC5X1X_VERF_2_75V 0 +#define TAC5X1X_VERF_2_5V 1 +#define TAC5X1X_VERF_1_375V 2 + +enum tac5x1x_type { + TAA5212 = 0, + TAA5412, + TAC5111, + TAC5112, + TAC5211, + TAC5212, + TAC5311, + TAC5312, + TAC5411, + TAC5412, + TAD5112, + TAD5212, +}; + +extern const struct regmap_config tac5x1x_regmap; +extern const struct of_device_id tac5x1x_of_match[]; + +int tac5x1x_probe(struct device *dev, struct regmap *regmap, + enum tac5x1x_type type); +int tac5x1x_remove(struct device *dev); + +#endif /* _TAC5X1X_H */

On Fri, Jun 06, 2025 at 12:21:33PM +0530, Niranjan H Y wrote:
tac5x1x family are series of low-power and high performance mono/stereo audio codecs consists of ADC and DAC combinations. The patch adds supports for Codecs(DAC & ADC), ADC only and DAC only configurations available in the tac5x1x family.
There's a few issues below but nothing that's *hugely* structural, the bulk of the code here looks good.
+config SND_SOC_TAC5X1X
- tristate "Texas Instruments TAC5X1X family codecs"
- depends on I2C && REGMAP_I2C
+config SND_SOC_TAC5X1X_I2C
- tristate "Texas Instruments TAC5X1X family driver based on I2C"
- depends on I2C && REGMAP_I2C
- select SND_SOC_TAC5X1X
You need to select REGMAP_I2C if you use it, it can't be turned on independently. If the device is I2C only then there's no need to have the second option for I2C, that's used for devices that support both I2C and SPI to avoid problems with dependencies on the I2C and SPI core code.
snd-soc-tas2781-i2c-y := tas2781-i2c.o +snd-soc-tac5x1x-y := tac5x1x.o +snd-soc-tac5x1x-i2c-y := tac5x1x-i2c.o snd-soc-tfa9879-y := tfa9879.o
Please keep these files alphanumerically sorted.
obj-$(CONFIG_SND_SOC_LPASS_TX_MACRO) += snd-soc-lpass-tx-macro.o
# Mux -obj-$(CONFIG_SND_SOC_SIMPLE_MUX) += snd-soc-simple-mux.o \ No newline at end of file +obj-$(CONFIG_SND_SOC_SIMPLE_MUX) += snd-soc-simple-mux.o diff --git a/sound/soc/codecs/tac5x1x-i2c.c b/sound/soc/codecs/tac5x1x-i2c.c
Looks like this whitespace change crept in accidentally.
+static int tac5x1x_i2c_probe(struct i2c_client *i2c) +{
- int ret;
- enum tac5x1x_type type;
- struct regmap *regmap;
- const struct regmap_config *config = &tac5x1x_regmap;
- regmap = devm_regmap_init_i2c(i2c, config);
- type = (uintptr_t)i2c_get_match_data(i2c);
- dev_info(&i2c->dev, "probing %s codec_type = %d\n",
i2c->name, type);
Just drop this print, it's probably a bit noisy.
+static const char * const int_ltch0[] = {
- "Clock Error",
- "PLL Lock",
- "Boost Over Temperature",
- "Boost Over Current",
- "Boost Mode",
- "Reserved",
- "Reserved",
- "Reserved",
+};
You can just set the maximum value for the enum to be whatever the maximum valid value is and then not need to list the Reserved entries at all.
+static const char * const out_ch2_ltch[] = {
- "OUT_CH2 OUT2P Short circuit Fault",
- "OUT_CH2 OUT2M Short circuit Fault",
- "OUT_CH2 DRVRP Virtual Ground Fault",
- "OUT_CH2 DRVRM Virtual ground Fault",
- "Reserved",
- "Reserved",
- "AREG SC Fault Mask",
- "AREG SC Fault",
+};
For ones where the reserved values are in the middle of the set of values you can use _VAL_ENUM() which lets you skip over the values that are invalid.
+static s32 tac5x1x_regmap_write(struct tac5x1x_priv *tac5x1x,
u32 reg, u32 value)
+{
- s32 ret;
- s32 retry_count = 5;
- while (retry_count--) {
ret = regmap_write(tac5x1x->regmap, reg,
value);
if (ret >= 0)
break;
usleep_range(5000, 5050);
- }
- if (retry_count == -1)
return 3;
- else
return ret;
+}
Is the hardware genuinely so unstable that we need to retry all the I/O? This seems really concerning.
+static s32 tac5x1x_regmap_read(struct tac5x1x_priv *tac5x1x,
u32 reg, u32 *value)
+{
- s32 ret;
- s32 retry_count = 5;
- ret = regmap_reinit_cache(tac5x1x->regmap, &tac5x1x_regmap);
- if (ret) {
dev_err(tac5x1x->dev, "Failed to reinit reg cache\n");
return ret;
- }
- while (retry_count--) {
ret = regmap_read(tac5x1x->regmap, reg,
value);
if (ret >= 0)
break;
usleep_range(5000, 5050);
- }
This seems *really* scary and confusing, why would we reset the register cache in what looks like a normal read operation.
+static s32 tac5x1x_dev_read(struct tac5x1x_priv *tac5x1x,
u32 dev_no, u32 reg,
u32 *ref_value)
+{
- s32 ret;
- guard(mutex)(&tac5x1x->dev_lock);
- if (dev_no < tac5x1x->ndev) {
ret = tac5x1x_regmap_write(tac5x1x,
TAC_PAGE_SELECT, 0);
if (ret < 0) {
dev_err(tac5x1x->dev, "%s, E=%d\n",
__func__, ret);
return ret;
}
This doesn't actually appear to do anything to support or choose between multiple devices? The code all looks like it only supports one device, and this is only used in the interrupt handler.
+static void tac5x1x_irq_work_func(struct tac5x1x_priv *tac5x1x) +{
- u32 reg_val, array_size, i, index = 0, bit = 0;
- s32 rc;
- tac5x1x_enable_irq(tac5x1x, false);
- array_size = ARRAY_SIZE(int_reg_array);
- for (i = 0; i < array_size; i++) {
rc = tac5x1x_dev_read(tac5x1x, index,
int_reg_array[i], ®_val);
...
- }
- tac5x1x_enable_irq(tac5x1x, true);
The interrupt disabling here seems odd - what's the story there? I see this is a work function rather than an irq thread to add some delay and introduce some debouncing but it's not clear why the disable during handling.
+const struct regmap_config tac5x1x_regmap = {
- .max_register = 12 * 128,
+EXPORT_SYMBOL(tac5x1x_regmap);
EXPORT_SYMBOL_GPL().
+static s32 tac5x1x_set_GPO1_gpio(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
+{
- struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
- s32 gpio_check, val;
- val = snd_soc_component_read(component, TAC5X1X_GPO1);
- gpio_check = ((val & TAC5X1X_GPIOX_CFG_MASK) >> 0);
- if (gpio_check != TAC5X1X_GPIO_GPO) {
dev_err(component->dev,
"%s: GPO1 is not configure as a GPO output\n",
__func__);
return -EINVAL;
- }
- if (ucontrol->value.integer.value[0])
val = 0;
- else
val = TAC5X1X_GPO1_VAL;
This seems to be exposing a GPIO directly to userspace, which will prevent using that GPIO with other kernel subsystems. It would be better to expose this via gpiolib, then if userspace control is needed that can be done through gpiolib.
+/* Impedance Selection */ +static const char *const resistor_text[] = {
- "5 kOhm",
- "10 kOhm",
- "40 kOhm",
+};
+static SOC_ENUM_SINGLE_DECL(adc1_resistor_enum, TAC5X1X_ADCCH1C0, 4,
resistor_text);
+static SOC_ENUM_SINGLE_DECL(adc2_resistor_enum, TAC5X1X_ADCCH2C0, 4,
resistor_text);
Is this something that would be adjusted at runtime, or should it be a device tree setting?
+static const char *const rx_ch3_asi_cfg_text[] = {
"Disable",
"DAC channel data",
+};
On/off switches should be plain controls ending in "Switch" rather than enums.
+static const char *const tac5x1x_slot_select_text[] = {
- "Slot 0", "Slot 1", "Slot 2", "Slot 3",
- "Slot 4", "Slot 5", "Slot 6", "Slot 7",
- "Slot 8", "Slot 9", "Slot 10", "Slot 11",
- "Slot 12", "Slot 13", "Slot 14", "Slot 15",
- "Slot 16", "Slot 17", "Slot 18", "Slot 19",
- "Slot 20", "Slot 21", "Slot 22", "Slot 23",
- "Slot 24", "Slot 25", "Slot 26", "Slot 27",
- "Slot 28", "Slot 29", "Slot 30", "Slot 31",
+};
TDM slot control would usually be done via set_tdm_slot().
+static const char *const out2x_vcom_text[] = {
- "0.6 * Vref",
- "AVDD by 2",
+};
+static const char *const diag_cfg_text[] = {
- "0mv", "30mv", "60mv", "90mv",
- "120mv", "150mv", "180mv", "210mv",
- "240mv", "270mv", "300mv", "330mv",
- "360mv", "390mv", "420mv", "450mv",
+};
+static const char *const diag_cfg_gnd_text[] = {
- "0mv", "60mv", "120mv", "180mv",
- "240mv", "300mv", "360mv", "420mv",
- "480mv", "540mv", "600mv", "660mv",
- "720mv", "780mv", "840mv", "900mv",
+};
Are these controls that should be device tree data?
- switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
SND_SOC_DAIFMT_CLOCK_MASK.
+#ifdef CONFIG_PM +static s32 tac5x1x_soc_suspend(struct snd_soc_component *component) +{
- struct tac5x1x_priv *tac5x1x =
snd_soc_component_get_drvdata(component);
- regcache_cache_only(tac5x1x->regmap, true);
- regcache_mark_dirty(tac5x1x->regmap);
- regulator_disable(tac5x1x->supply_avdd);
- regulator_disable(tac5x1x->supply_iovdd);
Consider using the regulator_bulk_ APIs - the current code is fine, but I don't see any cases where you're controlling the regulators separately so it'd be a little simpler and allows the core to do things like bring multiple regulators up in parallel.
+static s32 tac5x1x_soc_resume(struct snd_soc_component *component) +{
- struct tac5x1x_priv *tac5x1x =
snd_soc_component_get_drvdata(component);
- s32 ret;
- regcache_cache_only(tac5x1x->regmap, false);
- snd_soc_component_cache_sync(component);
- ret = regulator_enable(tac5x1x->supply_avdd);
- if (ret) {
regulator_disable(tac5x1x->supply_avdd);
return ret;
- }
- ret = regulator_enable(tac5x1x->supply_iovdd);
- if (ret) {
regulator_disable(tac5x1x->supply_iovdd);
return ret;
- }
This will try to do the cache sync with the regulators disabled which won't work if they were actually turned off.

tac5x1x family are series of low-power and high performance mono/stereo audio codecs consists of ADC and DAC combinations. The family consist of Codecs(DAC & ADC), ADC only and DAC only configurations. The documentation explains the list of devices in the family, their power supply configurations and gpio configuration options available for various functionality.
Signed-off-by: Niranjan H Y niranjan.hy@ti.com --- .../devicetree/bindings/sound/ti,tac5x1x.yaml | 222 ++++++++++++++++++ 1 file changed, 222 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/ti,tac5x1x.yaml
diff --git a/Documentation/devicetree/bindings/sound/ti,tac5x1x.yaml b/Documentation/devicetree/bindings/sound/ti,tac5x1x.yaml new file mode 100644 index 000000000000..b5f3f09a0465 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/ti,tac5x1x.yaml @@ -0,0 +1,222 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +# Copyright (C) 2025 Texas Instruments Incorporated +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/ti,tac5x1x.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Texas Instruments TAC5X1X Codec + +description: | + TAC5X1X are series of low-power and high performance mono or stereo + audio codecs, as well as multiple inputs and outputs programmable in + single-ended or fully differential configurations. Device supports both + Microphone and Line In input on ADC Channel. DAC Output can be configured + for either Line Out or Head Phone Load. + + The serial control bus supports SPI or I2C protocols, while the serial audio + data bus is programmable for I2S, left/right-justified, DSP, or TDM modes. + + Specification about the codecs can be found at: + https://www.ti.com/lit/gpn/taa5212 + https://www.ti.com/lit/gpn/taa5412-q1 + https://www.ti.com/lit/gpn/tac5111 + https://www.ti.com/lit/gpn/tac5112 + https://www.ti.com/lit/gpn/tac5211 + https://www.ti.com/lit/gpn/tac5212 + https://www.ti.com/lit/gpn/tac5311-q1 + https://www.ti.com/lit/gpn/tac5312-q1 + https://www.ti.com/lit/gpn/tac5411-q1 + https://www.ti.com/lit/gpn/tac5412-q1 + https://www.ti.com/lit/gpn/tad5112 + https://www.ti.com/lit/gpn/tad5212 + +maintainers: + - Niranjan H Y niranjan.hy@ti.com + - Kevin Lu kevin-lu@ti.com + +properties: + compatible: + enum: + - ti,taa5212 + - ti,taa5412 + - ti,tac5111 + - ti,tac5112 + - ti,tac5211 + - ti,tac5212 + - ti,tac5311 + - ti,tac5312 + - ti,tac5411 + - ti,tac5412 + - ti,tad5112 + - ti,tad5212 + + reg: + maxItems: 1 + + ti,vref: + description: VREF required voltage. If node is omitted then VREF is powered down. + $ref: /schemas/types.yaml#/definitions/uint32 + oneOf: + - const: 0 + description: VREF output is powered to 2.75V. + - const: 1 + description: VREF output is powered to 2.5V. + - const: 2 + description: VREF output is powered to 1.375V. + + ti,micbias-vg: + description: MicBias required voltage. If node is omitted then MicBias is powered down. + $ref: /schemas/types.yaml#/definitions/uint32 + oneOf: + - const: 0 + description: MICBIAS output is same as the VREF output + - const: 1 + description: MICBIAS output is 0.5 times the VREF output + - const: 3 + description: MICBIAS output is same as the AVDD + + avdd-supply: + description: Analog DAC voltage. + + iovdd-supply: + description: I/O voltage. + + ti,gpios-func: + description: | + Array indicating the GPIO1, GPIO2, GPO1 Functionality in the same order. + Each integer elemnent in the array represent the following + - 0 TAC5X1X_GPIO_DISABLE - GPIO is Disabled + - 1 TAC5X1X_GPIO_GPI - General Purpose Input + - 2 ADC3XXX_GPIO_GPO - General Purpose Output + - 3 TAC5X1X_GPIO_IRQ - Chip Interrupt + - 4 TAC5X1X_GPIO_PDMCLK - PDM CLK Output + - 5 TAC5X1X_GPIO_P_DOUT - Primary ASI DOUT + - 6 TAC5X1X_GPIO_P_DOUT2 - Primary ASI DOUT2 + - 7 TAC5X1X_GPIO_S_DOUT - Secondary ASI DOUT + - 8 TAC5X1X_GPIO_S_DOUT2 - Secondary ASI DOUT2 + - 9 TAC5X1X_GPIO_S_BCLK - Secondary BCLK Output + - 10 TAC5X1X_GPIO_S_FSYNC - Secondary FSYNC Output + - 11 TAC5X1X_GPIO_CLKOUT - General Purpose Output + - 12 TAC5X1X_GPIO_DOUT_MUX + - 13 TAC5X1X_GPIO_DAISY_OUT + $ref: /schemas/types.yaml#/definitions/uint32-array + minItems: 3 + maxItems: 3 + + ti,gpios-drive: + description: | + Array indicating the GPIO1, GPIO2, GPO1 Driver values + Each number in the array indicate the following driver values. + - 0 # Hi-Z Output + - 1 # Drive active low and active High + - 2 # Drive active low and weak High + - 3 # Drive acive low and Hi-Z + - 4 # Drive weak low and active High + - 5 # Drive Hi-Z and active High + $ref: /schemas/types.yaml#/definitions/uint32-array + minItems: 3 + maxItems: 3 + + ti,gpi1-func: + description: GPI1 Functionality + $ref: /schemas/types.yaml#/definitions/uint32 + enum: + - 0 # TAC5X1X_GPIO_DISABLE - I/O buffers powered down and not used + - 1 # TAC5X1X_GPIO_GPI - General purpose input + default: 0 + + '#sound-dai-cells': + const: 0 + + clocks: + maxItems: 1 + + ti,gpa-gpio: + description: GPA using GPIO1 configuration + $ref: /schemas/types.yaml#/definitions/uint32 + enum: + - 0 # GPA using GPIO1 is disabled + - 1 # GPA using GPIO1 + default: 0 + + ti,in-ch-en: + description: Enable Input channel diagnostics for TAC54XX and TAC53XX device. + $ref: /schemas/types.yaml#/definitions/uint32 + enum: + - 0 # Disable input channel diagnostics + - 1 # Enable input channel diagnostics + + ti,out-ch-en: + description: Enable Output channel diagnostics for TAC54XX and TAC53XX device + $ref: /schemas/types.yaml#/definitions/uint32 + enum: + - 0 # Disable Output channel diagnostics + - 1 # Enable Output channel Diagnostics + + ti,incl-se-inm: + description: INxM pin Diagnostics Scan Selection for Single Ended Configuration + $ref: /schemas/types.yaml#/definitions/uint32 + enum: + - 0 # INxM pin Diagnostics Scan Selection for Single Ended excluded for diagnosis + - 1 # INxM pin Diagnostics Scan Selection for Single Ended included for diagnosis + + ti,incl-ac-coup: + description: AC coupled channels pins Scan Selection for Diagnostics + $ref: /schemas/types.yaml#/definitions/uint32 + enum: + - 0 # AC coupled channels pins Scan Selection for Diagnostics exluded for diagnosis + - 1 # AC coupled channels pins Scan Selection for Diagnostics included for diagnosis + + ti,micbias-threshold: + description: Micbias Low and High threshold values for TAC54XX and TAC53XX series + $ref: /schemas/types.yaml#/definitions/uint32-array + maxItems: 2 + minItems: 2 + items: + minimum: 72 + maximum: 162 + + ti,gpa-threshold: + description: GPA Low and High threshold Values + $ref: /schemas/types.yaml#/definitions/uint32-array + maxItems: 2 + minItems: 2 + items: + minimum: 75 + maximum: 186 + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + #include <dt-bindings/gpio/gpio.h> + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + tac5x1x: tac5x1x@52 { + compatible = "ti,tac5212"; + reg = <0x52>; + #sound-dai-cells = <0>; + avdd-supply = <&vdd_3v3_reg>; + iovdd-supply = <&vdd_3v3_reg>; + ti,vref = <0>; + ti,micbias-vg = <3>; + ti,gpi1-func = <0>; + ti,gpios-func = <4>, <1>, <0>; + ti,gpios-drive = <0>, <0>, <0>; + ti,gpa-gpio = <0>; + ti,in-ch-en = <1>; + ti,out-ch-en = <1>; + ti,incl-ac-coup = <0>; + ti,incl-se-inm = <0>; + ti,gpa-threshold = <75>, <186>; + }; + }; +...

tac5x1x codec driver suporrts tac5x1x family which includes the following ADCs and DACs. So removed the duplicate entries in the pcm6240 i2c driver.
Signed-off-by: Niranjan H Y niranjan.hy@ti.com --- sound/soc/codecs/pcm6240.c | 124 +------------------------------------ sound/soc/codecs/pcm6240.h | 4 -- 2 files changed, 3 insertions(+), 125 deletions(-)
diff --git a/sound/soc/codecs/pcm6240.c b/sound/soc/codecs/pcm6240.c index 75af12231d1d..bbf3eb18bf54 100644 --- a/sound/soc/codecs/pcm6240.c +++ b/sound/soc/codecs/pcm6240.c @@ -44,10 +44,6 @@ static const struct i2c_device_id pcmdevice_i2c_id[] = { { "pcmd3140", PCMD3140 }, { "pcmd3180", PCMD3180 }, { "pcmd512x", PCMD512X }, - { "taa5212", TAA5212 }, - { "taa5412", TAA5412 }, - { "tad5212", TAD5212 }, - { "tad5412", TAD5412 }, {} }; MODULE_DEVICE_TABLE(i2c, pcmdevice_i2c_id); @@ -442,60 +438,6 @@ static const struct pcmdevice_mixer_control pcmd3180_fine_gain_ctl[] = { } };
-static const struct pcmdevice_mixer_control taa5412_digi_vol_ctl[] = { - { - .shift = 0, - .reg = TAA5412_REG_CH1_DIGITAL_VOLUME, - .max = 0xff, - .invert = 0, - }, - { - .shift = 0, - .reg = TAA5412_REG_CH2_DIGITAL_VOLUME, - .max = 0xff, - .invert = 0, - }, - { - .shift = 0, - .reg = TAA5412_REG_CH3_DIGITAL_VOLUME, - .max = 0xff, - .invert = 0, - }, - { - .shift = 0, - .reg = TAA5412_REG_CH4_DIGITAL_VOLUME, - .max = 0xff, - .invert = 0, - } -}; - -static const struct pcmdevice_mixer_control taa5412_fine_gain_ctl[] = { - { - .shift = 4, - .reg = TAA5412_REG_CH1_FINE_GAIN, - .max = 0xf, - .invert = 0, - }, - { - .shift = 4, - .reg = TAA5412_REG_CH2_FINE_GAIN, - .max = 0xf, - .invert = 0, - }, - { - .shift = 4, - .reg = TAA5412_REG_CH3_FINE_GAIN, - .max = 0xf, - .invert = 4, - }, - { - .shift = 0, - .reg = TAA5412_REG_CH4_FINE_GAIN, - .max = 0xf, - .invert = 4, - } -}; - static const DECLARE_TLV_DB_MINMAX_MUTE(pcmd3140_dig_gain_tlv, -10000, 2700); static const DECLARE_TLV_DB_MINMAX_MUTE(pcm1690_fine_dig_gain_tlv, @@ -512,7 +454,7 @@ static const DECLARE_TLV_DB_MINMAX_MUTE(pcm6260_fgain_tlv, static const DECLARE_TLV_DB_LINEAR(pcm6260_chgain_tlv, 0, 4200); static const DECLARE_TLV_DB_MINMAX_MUTE(taa5412_dig_vol_tlv, -8050, 4700); -static const DECLARE_TLV_DB_LINEAR(taa5412_fine_gain_tlv, +static const DECLARE_TLV_DB_LINEAR(pcmd31x0_fine_gain_tlv, -80, 70);
static int pcmdev_change_dev(struct pcmdevice_priv *pcm_priv, @@ -981,7 +923,7 @@ static const struct pcmdev_ctrl_info pcmdev_gain_ctl_info[][2] = { // PCMD3140 { { - .gain = taa5412_fine_gain_tlv, + .gain = pcmd31x0_fine_gain_tlv, .pcmdev_ctrl = pcmd3140_fine_gain_ctl, .ctrl_array_size = ARRAY_SIZE(pcmd3140_fine_gain_ctl), .get = pcmdevice_get_volsw, @@ -1000,7 +942,7 @@ static const struct pcmdev_ctrl_info pcmdev_gain_ctl_info[][2] = { // PCMD3180 { { - .gain = taa5412_fine_gain_tlv, + .gain = pcmd31x0_fine_gain_tlv, .pcmdev_ctrl = pcmd3180_fine_gain_ctl, .ctrl_array_size = ARRAY_SIZE(pcmd3180_fine_gain_ctl), .get = pcmdevice_get_volsw, @@ -1025,62 +967,6 @@ static const struct pcmdev_ctrl_info pcmdev_gain_ctl_info[][2] = { .ctrl_array_size = 0, }, }, - // TAA5212 - { - { - .gain = taa5412_fine_gain_tlv, - .pcmdev_ctrl = taa5412_fine_gain_ctl, - .ctrl_array_size = ARRAY_SIZE(taa5412_fine_gain_ctl), - .get = pcmdevice_get_volsw, - .put = pcmdevice_put_volsw, - .pcmdev_ctrl_name_id = 2, - }, - { - .gain = taa5412_dig_vol_tlv, - .pcmdev_ctrl = taa5412_digi_vol_ctl, - .ctrl_array_size = ARRAY_SIZE(taa5412_digi_vol_ctl), - .get = pcmdevice_get_volsw, - .put = pcmdevice_put_volsw, - .pcmdev_ctrl_name_id = 1, - }, - }, - // TAA5412 - { - { - .gain = taa5412_fine_gain_tlv, - .pcmdev_ctrl = taa5412_fine_gain_ctl, - .ctrl_array_size = ARRAY_SIZE(taa5412_fine_gain_ctl), - .get = pcmdevice_get_volsw, - .put = pcmdevice_put_volsw, - .pcmdev_ctrl_name_id = 2, - }, - { - .gain = taa5412_dig_vol_tlv, - .pcmdev_ctrl = taa5412_digi_vol_ctl, - .ctrl_array_size = ARRAY_SIZE(taa5412_digi_vol_ctl), - .get = pcmdevice_get_volsw, - .put = pcmdevice_put_volsw, - .pcmdev_ctrl_name_id = 1, - }, - }, - // TAD5212 - { - { - .ctrl_array_size = 0, - }, - { - .ctrl_array_size = 0, - }, - }, - // TAD5412 - { - { - .ctrl_array_size = 0, - }, - { - .ctrl_array_size = 0, - }, - }, };
static int pcmdev_dev_bulk_write(struct pcmdevice_priv *pcm_dev, @@ -2002,10 +1888,6 @@ static const struct of_device_id pcmdevice_of_match[] = { { .compatible = "ti,pcmd3140" }, { .compatible = "ti,pcmd3180" }, { .compatible = "ti,pcmd512x" }, - { .compatible = "ti,taa5212" }, - { .compatible = "ti,taa5412" }, - { .compatible = "ti,tad5212" }, - { .compatible = "ti,tad5412" }, {}, }; MODULE_DEVICE_TABLE(of, pcmdevice_of_match); diff --git a/sound/soc/codecs/pcm6240.h b/sound/soc/codecs/pcm6240.h index 2d8f9e798139..86b1ef734a3d 100644 --- a/sound/soc/codecs/pcm6240.h +++ b/sound/soc/codecs/pcm6240.h @@ -33,10 +33,6 @@ enum pcm_device { PCMD3140, PCMD3180, PCMD512X, - TAA5212, - TAA5412, - TAD5212, - TAD5412, MAX_DEVICE, };

Removed taa* and tad* device from the support list as these devices are supported by tac5x1x codec driver
Signed-off-by: Niranjan H Y niranjan.hy@ti.com --- .../devicetree/bindings/sound/ti,pcm6240.yaml | 10 ---------- 1 file changed, 10 deletions(-)
diff --git a/Documentation/devicetree/bindings/sound/ti,pcm6240.yaml b/Documentation/devicetree/bindings/sound/ti,pcm6240.yaml index d89b4255b51c..b0d5f57dc0f5 100644 --- a/Documentation/devicetree/bindings/sound/ti,pcm6240.yaml +++ b/Documentation/devicetree/bindings/sound/ti,pcm6240.yaml @@ -29,8 +29,6 @@ description: | https://www.ti.com/lit/gpn/pcm9211 https://www.ti.com/lit/gpn/pcmd3140 https://www.ti.com/lit/gpn/pcmd3180 - https://www.ti.com/lit/gpn/taa5212 - https://www.ti.com/lit/gpn/tad5212
properties: compatible: @@ -81,10 +79,6 @@ properties: ti,pcmd3180: Eight-channel pulse-density-modulation input to TDM or I2S output converter.
- ti,taa5212: Low-power high-performance stereo audio ADC with 118-dB - dynamic range. - - ti,tad5212: Low-power stereo audio DAC with 120-dB dynamic range. oneOf: - items: - enum: @@ -98,8 +92,6 @@ properties: - enum: - ti,pcmd512x - ti,pcm9211 - - ti,taa5212 - - ti,tad5212 - const: ti,adc6120 - items: - enum: @@ -114,8 +106,6 @@ properties: - ti,pcmd3140 - ti,pcmd3180 - ti,pcm1690 - - ti,taa5412 - - ti,tad5412 - const: ti,pcm6240 - enum: - ti,adc6120
participants (2)
-
Mark Brown
-
Niranjan H Y