Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ASoC: PCM6240: New driver

Merge series from Shenghao Ding <shenghao-ding@ti.com>:

mixer-test report:
root@am335x-evm:/bin# mixer-test
TAP version 13
# Card 0 - TI BeagleBone Black (TI BeagleBone Black)
1..455
ok 1 get_value.0.64
# 0.64 PCMD3180 i2c2 Profile id
ok 2 name.0.64
ok 3 write_default.0.64
ok 4 write_valid.0.64
ok 5 write_invalid.0.64
ok 6 event_missing.0.64
ok 7 event_spurious.0.64
ok 8 get_value.0.63
# 0.63 PCMD3180 i2c2 Dev3 Ch8 Digi Volume
ok 9 name.0.63
ok 10 write_default.0.63
ok 11 write_valid.0.63
ok 12 write_invalid.0.63
ok 13 event_missing.0.63
ok 14 event_spurious.0.63
ok 15 get_value.0.62
# 0.62 PCMD3180 i2c2 Dev3 Ch7 Digi Volume
ok 16 name.0.62
ok 17 write_default.0.62
ok 18 write_valid.0.62
ok 19 write_invalid.0.62
ok 20 event_missing.0.62
ok 21 event_spurious.0.62
ok 22 get_value.0.61
# 0.61 PCMD3180 i2c2 Dev3 Ch6 Digi Volume
ok 23 name.0.61
ok 24 write_default.0.61
ok 25 write_valid.0.61
ok 26 write_invalid.0.61
ok 27 event_missing.0.61
ok 28 event_spurious.0.61
ok 29 get_value.0.60
# 0.60 PCMD3180 i2c2 Dev3 Ch5 Digi Volume
ok 30 name.0.60
ok 31 write_default.0.60
ok 32 write_valid.0.60
ok 33 write_invalid.0.60
ok 34 event_missing.0.60
ok 35 event_spurious.0.60
ok 36 get_value.0.59
# 0.59 PCMD3180 i2c2 Dev3 Ch4 Digi Volume
ok 37 name.0.59
ok 38 write_default.0.59
ok 39 write_valid.0.59
ok 40 write_invalid.0.59
ok 41 event_missing.0.59
ok 42 event_spurious.0.59
ok 43 get_value.0.58
# 0.58 PCMD3180 i2c2 Dev3 Ch3 Digi Volume
ok 44 name.0.58
ok 45 write_default.0.58
ok 46 write_valid.0.58
ok 47 write_invalid.0.58
ok 48 event_missing.0.58
ok 49 event_spurious.0.58
ok 50 get_value.0.57
# 0.57 PCMD3180 i2c2 Dev3 Ch2 Digi Volume
ok 51 name.0.57
ok 52 write_default.0.57
ok 53 write_valid.0.57
ok 54 write_invalid.0.57
ok 55 event_missing.0.57
ok 56 event_spurious.0.57
ok 57 get_value.0.56
# 0.56 PCMD3180 i2c2 Dev3 Ch1 Digi Volume
ok 58 name.0.56
ok 59 write_default.0.56
ok 60 write_valid.0.56
ok 61 write_invalid.0.56
ok 62 event_missing.0.56
ok 63 event_spurious.0.56
ok 64 get_value.0.55
# 0.55 PCMD3180 i2c2 Dev3 Ch8 Fine Volume
ok 65 name.0.55
ok 66 write_default.0.55
ok 67 write_valid.0.55
ok 68 write_invalid.0.55
ok 69 event_missing.0.55
ok 70 event_spurious.0.55
ok 71 get_value.0.54
# 0.54 PCMD3180 i2c2 Dev3 Ch7 Fine Volume
ok 72 name.0.54
ok 73 write_default.0.54
ok 74 write_valid.0.54
ok 75 write_invalid.0.54
ok 76 event_missing.0.54
ok 77 event_spurious.0.54
ok 78 get_value.0.53
# 0.53 PCMD3180 i2c2 Dev3 Ch6 Fine Volume
ok 79 name.0.53
ok 80 write_default.0.53
ok 81 write_valid.0.53
ok 82 write_invalid.0.53
ok 83 event_missing.0.53
ok 84 event_spurious.0.53
ok 85 get_value.0.52
# 0.52 PCMD3180 i2c2 Dev3 Ch5 Fine Volume
ok 86 name.0.52
ok 87 write_default.0.52
ok 88 write_valid.0.52
ok 89 write_invalid.0.52
ok 90 event_missing.0.52
ok 91 event_spurious.0.52
ok 92 get_value.0.51
# 0.51 PCMD3180 i2c2 Dev3 Ch4 Fine Volume
ok 93 name.0.51
ok 94 write_default.0.51
ok 95 write_valid.0.51
ok 96 write_invalid.0.51
ok 97 event_missing.0.51
ok 98 event_spurious.0.51
ok 99 get_value.0.50
# 0.50 PCMD3180 i2c2 Dev3 Ch3 Fine Volume
ok 100 name.0.50
ok 101 write_default.0.50
ok 102 write_valid.0.50
ok 103 write_invalid.0.50
ok 104 event_missing.0.50
ok 105 event_spurious.0.50
ok 106 get_value.0.49
# 0.49 PCMD3180 i2c2 Dev3 Ch2 Fine Volume
ok 107 name.0.49
ok 108 write_default.0.49
ok 109 write_valid.0.49
ok 110 write_invalid.0.49
ok 111 event_missing.0.49
ok 112 event_spurious.0.49
ok 113 get_value.0.48
# 0.48 PCMD3180 i2c2 Dev3 Ch1 Fine Volume
ok 114 name.0.48
ok 115 write_default.0.48
ok 116 write_valid.0.48
ok 117 write_invalid.0.48
ok 118 event_missing.0.48
ok 119 event_spurious.0.48
ok 120 get_value.0.47
# 0.47 PCMD3180 i2c2 Dev2 Ch8 Digi Volume
ok 121 name.0.47
ok 122 write_default.0.47
ok 123 write_valid.0.47
ok 124 write_invalid.0.47
ok 125 event_missing.0.47
ok 126 event_spurious.0.47
ok 127 get_value.0.46
# 0.46 PCMD3180 i2c2 Dev2 Ch7 Digi Volume
ok 128 name.0.46
ok 129 write_default.0.46
ok 130 write_valid.0.46
ok 131 write_invalid.0.46
ok 132 event_missing.0.46
ok 133 event_spurious.0.46
ok 134 get_value.0.45
# 0.45 PCMD3180 i2c2 Dev2 Ch6 Digi Volume
ok 135 name.0.45
ok 136 write_default.0.45
ok 137 write_valid.0.45
ok 138 write_invalid.0.45
ok 139 event_missing.0.45
ok 140 event_spurious.0.45
ok 141 get_value.0.44
# 0.44 PCMD3180 i2c2 Dev2 Ch5 Digi Volume
ok 142 name.0.44
ok 143 write_default.0.44
ok 144 write_valid.0.44
ok 145 write_invalid.0.44
ok 146 event_missing.0.44
ok 147 event_spurious.0.44
ok 148 get_value.0.43
# 0.43 PCMD3180 i2c2 Dev2 Ch4 Digi Volume
ok 149 name.0.43
ok 150 write_default.0.43
ok 151 write_valid.0.43
ok 152 write_invalid.0.43
ok 153 event_missing.0.43
ok 154 event_spurious.0.43
ok 155 get_value.0.42
# 0.42 PCMD3180 i2c2 Dev2 Ch3 Digi Volume
ok 156 name.0.42
ok 157 write_default.0.42
ok 158 write_valid.0.42
ok 159 write_invalid.0.42
ok 160 event_missing.0.42
ok 161 event_spurious.0.42
ok 162 get_value.0.41
# 0.41 PCMD3180 i2c2 Dev2 Ch2 Digi Volume
ok 163 name.0.41
ok 164 write_default.0.41
ok 165 write_valid.0.41
ok 166 write_invalid.0.41
ok 167 event_missing.0.41
ok 168 event_spurious.0.41
ok 169 get_value.0.40
# 0.40 PCMD3180 i2c2 Dev2 Ch1 Digi Volume
ok 170 name.0.40
ok 171 write_default.0.40
ok 172 write_valid.0.40
ok 173 write_invalid.0.40
ok 174 event_missing.0.40
ok 175 event_spurious.0.40
ok 176 get_value.0.39
# 0.39 PCMD3180 i2c2 Dev2 Ch8 Fine Volume
ok 177 name.0.39
ok 178 write_default.0.39
ok 179 write_valid.0.39
ok 180 write_invalid.0.39
ok 181 event_missing.0.39
ok 182 event_spurious.0.39
ok 183 get_value.0.38
# 0.38 PCMD3180 i2c2 Dev2 Ch7 Fine Volume
ok 184 name.0.38
ok 185 write_default.0.38
ok 186 write_valid.0.38
ok 187 write_invalid.0.38
ok 188 event_missing.0.38
ok 189 event_spurious.0.38
ok 190 get_value.0.37
# 0.37 PCMD3180 i2c2 Dev2 Ch6 Fine Volume
ok 191 name.0.37
ok 192 write_default.0.37
ok 193 write_valid.0.37
ok 194 write_invalid.0.37
ok 195 event_missing.0.37
ok 196 event_spurious.0.37
ok 197 get_value.0.36
# 0.36 PCMD3180 i2c2 Dev2 Ch5 Fine Volume
ok 198 name.0.36
ok 199 write_default.0.36
ok 200 write_valid.0.36
ok 201 write_invalid.0.36
ok 202 event_missing.0.36
ok 203 event_spurious.0.36
ok 204 get_value.0.35
# 0.35 PCMD3180 i2c2 Dev2 Ch4 Fine Volume
ok 205 name.0.35
ok 206 write_default.0.35
ok 207 write_valid.0.35
ok 208 write_invalid.0.35
ok 209 event_missing.0.35
ok 210 event_spurious.0.35
ok 211 get_value.0.34
# 0.34 PCMD3180 i2c2 Dev2 Ch3 Fine Volume
ok 212 name.0.34
ok 213 write_default.0.34
ok 214 write_valid.0.34
ok 215 write_invalid.0.34
ok 216 event_missing.0.34
ok 217 event_spurious.0.34
ok 218 get_value.0.33
# 0.33 PCMD3180 i2c2 Dev2 Ch2 Fine Volume
ok 219 name.0.33
ok 220 write_default.0.33
ok 221 write_valid.0.33
ok 222 write_invalid.0.33
ok 223 event_missing.0.33
ok 224 event_spurious.0.33
ok 225 get_value.0.32
# 0.32 PCMD3180 i2c2 Dev2 Ch1 Fine Volume
ok 226 name.0.32
ok 227 write_default.0.32
ok 228 write_valid.0.32
ok 229 write_invalid.0.32
ok 230 event_missing.0.32
ok 231 event_spurious.0.32
ok 232 get_value.0.31
# 0.31 PCMD3180 i2c2 Dev1 Ch8 Digi Volume
ok 233 name.0.31
ok 234 write_default.0.31
ok 235 write_valid.0.31
ok 236 write_invalid.0.31
ok 237 event_missing.0.31
ok 238 event_spurious.0.31
ok 239 get_value.0.30
# 0.30 PCMD3180 i2c2 Dev1 Ch7 Digi Volume
ok 240 name.0.30
ok 241 write_default.0.30
ok 242 write_valid.0.30
ok 243 write_invalid.0.30
ok 244 event_missing.0.30
ok 245 event_spurious.0.30
ok 246 get_value.0.29
# 0.29 PCMD3180 i2c2 Dev1 Ch6 Digi Volume
ok 247 name.0.29
ok 248 write_default.0.29
ok 249 write_valid.0.29
ok 250 write_invalid.0.29
ok 251 event_missing.0.29
ok 252 event_spurious.0.29
ok 253 get_value.0.28
# 0.28 PCMD3180 i2c2 Dev1 Ch5 Digi Volume
ok 254 name.0.28
ok 255 write_default.0.28
ok 256 write_valid.0.28
ok 257 write_invalid.0.28
ok 258 event_missing.0.28
ok 259 event_spurious.0.28
ok 260 get_value.0.27
# 0.27 PCMD3180 i2c2 Dev1 Ch4 Digi Volume
ok 261 name.0.27
ok 262 write_default.0.27
ok 263 write_valid.0.27
ok 264 write_invalid.0.27
ok 265 event_missing.0.27
ok 266 event_spurious.0.27
ok 267 get_value.0.26
# 0.26 PCMD3180 i2c2 Dev1 Ch3 Digi Volume
ok 268 name.0.26
ok 269 write_default.0.26
ok 270 write_valid.0.26
ok 271 write_invalid.0.26
ok 272 event_missing.0.26
ok 273 event_spurious.0.26
ok 274 get_value.0.25
# 0.25 PCMD3180 i2c2 Dev1 Ch2 Digi Volume
ok 275 name.0.25
ok 276 write_default.0.25
ok 277 write_valid.0.25
ok 278 write_invalid.0.25
ok 279 event_missing.0.25
ok 280 event_spurious.0.25
ok 281 get_value.0.24
# 0.24 PCMD3180 i2c2 Dev1 Ch1 Digi Volume
ok 282 name.0.24
ok 283 write_default.0.24
ok 284 write_valid.0.24
ok 285 write_invalid.0.24
ok 286 event_missing.0.24
ok 287 event_spurious.0.24
ok 288 get_value.0.23
# 0.23 PCMD3180 i2c2 Dev1 Ch8 Fine Volume
ok 289 name.0.23
ok 290 write_default.0.23
ok 291 write_valid.0.23
ok 292 write_invalid.0.23
ok 293 event_missing.0.23
ok 294 event_spurious.0.23
ok 295 get_value.0.22
# 0.22 PCMD3180 i2c2 Dev1 Ch7 Fine Volume
ok 296 name.0.22
ok 297 write_default.0.22
ok 298 write_valid.0.22
ok 299 write_invalid.0.22
ok 300 event_missing.0.22
ok 301 event_spurious.0.22
ok 302 get_value.0.21
# 0.21 PCMD3180 i2c2 Dev1 Ch6 Fine Volume
ok 303 name.0.21
ok 304 write_default.0.21
ok 305 write_valid.0.21
ok 306 write_invalid.0.21
ok 307 event_missing.0.21
ok 308 event_spurious.0.21
ok 309 get_value.0.20
# 0.20 PCMD3180 i2c2 Dev1 Ch5 Fine Volume
ok 310 name.0.20
ok 311 write_default.0.20
ok 312 write_valid.0.20
ok 313 write_invalid.0.20
ok 314 event_missing.0.20
ok 315 event_spurious.0.20
ok 316 get_value.0.19
# 0.19 PCMD3180 i2c2 Dev1 Ch4 Fine Volume
ok 317 name.0.19
ok 318 write_default.0.19
ok 319 write_valid.0.19
ok 320 write_invalid.0.19
ok 321 event_missing.0.19
ok 322 event_spurious.0.19
ok 323 get_value.0.18
# 0.18 PCMD3180 i2c2 Dev1 Ch3 Fine Volume
ok 324 name.0.18
ok 325 write_default.0.18
ok 326 write_valid.0.18
ok 327 write_invalid.0.18
ok 328 event_missing.0.18
ok 329 event_spurious.0.18
ok 330 get_value.0.17
# 0.17 PCMD3180 i2c2 Dev1 Ch2 Fine Volume
ok 331 name.0.17
ok 332 write_default.0.17
ok 333 write_valid.0.17
ok 334 write_invalid.0.17
ok 335 event_missing.0.17
ok 336 event_spurious.0.17
ok 337 get_value.0.16
# 0.16 PCMD3180 i2c2 Dev1 Ch1 Fine Volume
ok 338 name.0.16
ok 339 write_default.0.16
ok 340 write_valid.0.16
ok 341 write_invalid.0.16
ok 342 event_missing.0.16
ok 343 event_spurious.0.16
ok 344 get_value.0.15
# 0.15 PCMD3180 i2c2 Dev0 Ch8 Digi Volume
ok 345 name.0.15
ok 346 write_default.0.15
ok 347 write_valid.0.15
ok 348 write_invalid.0.15
ok 349 event_missing.0.15
ok 350 event_spurious.0.15
ok 351 get_value.0.14
# 0.14 PCMD3180 i2c2 Dev0 Ch7 Digi Volume
ok 352 name.0.14
ok 353 write_default.0.14
ok 354 write_valid.0.14
ok 355 write_invalid.0.14
ok 356 event_missing.0.14
ok 357 event_spurious.0.14
ok 358 get_value.0.13
# 0.13 PCMD3180 i2c2 Dev0 Ch6 Digi Volume
ok 359 name.0.13
ok 360 write_default.0.13
ok 361 write_valid.0.13
ok 362 write_invalid.0.13
ok 363 event_missing.0.13
ok 364 event_spurious.0.13
ok 365 get_value.0.12
# 0.12 PCMD3180 i2c2 Dev0 Ch5 Digi Volume
ok 366 name.0.12
ok 367 write_default.0.12
ok 368 write_valid.0.12
ok 369 write_invalid.0.12
ok 370 event_missing.0.12
ok 371 event_spurious.0.12
ok 372 get_value.0.11
# 0.11 PCMD3180 i2c2 Dev0 Ch4 Digi Volume
ok 373 name.0.11
ok 374 write_default.0.11
ok 375 write_valid.0.11
ok 376 write_invalid.0.11
ok 377 event_missing.0.11
ok 378 event_spurious.0.11
ok 379 get_value.0.10
# 0.10 PCMD3180 i2c2 Dev0 Ch3 Digi Volume
ok 380 name.0.10
ok 381 write_default.0.10
ok 382 write_valid.0.10
ok 383 write_invalid.0.10
ok 384 event_missing.0.10
ok 385 event_spurious.0.10
ok 386 get_value.0.9
# 0.9 PCMD3180 i2c2 Dev0 Ch2 Digi Volume
ok 387 name.0.9
ok 388 write_default.0.9
ok 389 write_valid.0.9
ok 390 write_invalid.0.9
ok 391 event_missing.0.9
ok 392 event_spurious.0.9
ok 393 get_value.0.8
# 0.8 PCMD3180 i2c2 Dev0 Ch1 Digi Volume
ok 394 name.0.8
ok 395 write_default.0.8
ok 396 write_valid.0.8
ok 397 write_invalid.0.8
ok 398 event_missing.0.8
ok 399 event_spurious.0.8
ok 400 get_value.0.7
# 0.7 PCMD3180 i2c2 Dev0 Ch8 Fine Volume
ok 401 name.0.7
ok 402 write_default.0.7
ok 403 write_valid.0.7
ok 404 write_invalid.0.7
ok 405 event_missing.0.7
ok 406 event_spurious.0.7
ok 407 get_value.0.6
# 0.6 PCMD3180 i2c2 Dev0 Ch7 Fine Volume
ok 408 name.0.6
ok 409 write_default.0.6
ok 410 write_valid.0.6
ok 411 write_invalid.0.6
ok 412 event_missing.0.6
ok 413 event_spurious.0.6
ok 414 get_value.0.5
# 0.5 PCMD3180 i2c2 Dev0 Ch6 Fine Volume
ok 415 name.0.5
ok 416 write_default.0.5
ok 417 write_valid.0.5
ok 418 write_invalid.0.5
ok 419 event_missing.0.5
ok 420 event_spurious.0.5
ok 421 get_value.0.4
# 0.4 PCMD3180 i2c2 Dev0 Ch5 Fine Volume
ok 422 name.0.4
ok 423 write_default.0.4
ok 424 write_valid.0.4
ok 425 write_invalid.0.4
ok 426 event_missing.0.4
ok 427 event_spurious.0.4
ok 428 get_value.0.3
# 0.3 PCMD3180 i2c2 Dev0 Ch4 Fine Volume
ok 429 name.0.3
ok 430 write_default.0.3
ok 431 write_valid.0.3
ok 432 write_invalid.0.3
ok 433 event_missing.0.3
ok 434 event_spurious.0.3
ok 435 get_value.0.2
# 0.2 PCMD3180 i2c2 Dev0 Ch3 Fine Volume
ok 436 name.0.2
ok 437 write_default.0.2
ok 438 write_valid.0.2
ok 439 write_invalid.0.2
ok 440 event_missing.0.2
ok 441 event_spurious.0.2
ok 442 get_value.0.1
# 0.1 PCMD3180 i2c2 Dev0 Ch2 Fine Volume
ok 443 name.0.1
ok 444 write_default.0.1
ok 445 write_valid.0.1
ok 446 write_invalid.0.1
ok 447 event_missing.0.1
ok 448 event_spurious.0.1
ok 449 get_value.0.0
# 0.0 PCMD3180 i2c2 Dev0 Ch1 Fine Volume
ok 450 name.0.0
ok 451 write_default.0.0
ok 452 write_valid.0.0
ok 453 write_invalid.0.0
ok 454 event_missing.0.0
ok 455 event_spurious.0.0
# Totals: pass:455 fail:0 xfail:0 xpass:0 skip:0 error:0

+2658
+177
Documentation/devicetree/bindings/sound/ti,pcm6240.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + # Copyright (C) 2022 - 2024 Texas Instruments Incorporated 3 + %YAML 1.2 4 + --- 5 + $id: http://devicetree.org/schemas/sound/ti,pcm6240.yaml# 6 + $schema: http://devicetree.org/meta-schemas/core.yaml# 7 + 8 + title: Texas Instruments PCM6240 Family Audio ADC/DAC 9 + 10 + maintainers: 11 + - Shenghao Ding <shenghao-ding@ti.com> 12 + 13 + description: | 14 + The PCM6240 Family is a big family of Audio ADC/DAC for 15 + different Specifications, range from Personal Electric 16 + to Automotive Electric, even some professional fields. 17 + 18 + Specifications about the audio chip can be found at: 19 + https://www.ti.com/lit/gpn/tlv320adc3120 20 + https://www.ti.com/lit/gpn/tlv320adc5120 21 + https://www.ti.com/lit/gpn/tlv320adc6120 22 + https://www.ti.com/lit/gpn/dix4192 23 + https://www.ti.com/lit/gpn/pcm1690 24 + https://www.ti.com/lit/gpn/pcm3120-q1 25 + https://www.ti.com/lit/gpn/pcm3140-q1 26 + https://www.ti.com/lit/gpn/pcm5120-q1 27 + https://www.ti.com/lit/gpn/pcm6120-q1 28 + https://www.ti.com/lit/gpn/pcm6260-q1 29 + https://www.ti.com/lit/gpn/pcm9211 30 + https://www.ti.com/lit/gpn/pcmd3140 31 + https://www.ti.com/lit/gpn/pcmd3180 32 + https://www.ti.com/lit/gpn/taa5212 33 + https://www.ti.com/lit/gpn/tad5212 34 + 35 + properties: 36 + compatible: 37 + description: | 38 + ti,adc3120: Stereo-channel, 768-kHz, Burr-Brown™ audio analog-to- 39 + digital converter (ADC) with 106-dB SNR. 40 + 41 + ti,adc5120: 2-Channel, 768-kHz, Burr-Brown™ Audio ADC with 120-dB SNR. 42 + 43 + ti,adc6120: Stereo-channel, 768-kHz, Burr-Brown™ audio analog-to- 44 + digital converter (ADC) with 123-dB SNR. 45 + 46 + ti,dix4192: 216-kHz digital audio converter with Quad-Channel In 47 + and One-Channel Out. 48 + 49 + ti,pcm1690: Automotive Catalog 113dB SNR 8-Channel Audio DAC with 50 + Differential Outputs. 51 + 52 + ti,pcm3120: Automotive, stereo, 106-dB SNR, 768-kHz, low-power 53 + software-controlled audio ADC. 54 + 55 + ti,pcm3140: Automotive, Quad-Channel, 768-kHz, Burr-Brown™ Audio ADC 56 + with 106-dB SNR. 57 + 58 + ti,pcm5120: Automotive, stereo, 120-dB SNR, 768-kHz, low-power 59 + software-controlled audio ADC. 60 + 61 + ti,pcm5140: Automotive, Quad-Channel, 768-kHz, Burr-Brown™ Audio ADC 62 + with 120-dB SNR. 63 + 64 + ti,pcm6120: Automotive, stereo, 123-dB SNR, 768-kHz, low-power 65 + software-controlled audio ADC. 66 + 67 + ti,pcm6140: Automotive, Quad-Channel, 768-kHz, Burr-Brown™ Audio ADC 68 + with 123-dB SNR. 69 + 70 + ti,pcm6240: Automotive 4-ch audio ADC with integrated programmable mic 71 + bias, boost and input diagnostics. 72 + 73 + ti,pcm6260: Automotive 6-ch audio ADC with integrated programmable mic 74 + bias, boost and input diagnostics. 75 + 76 + ti,pcm9211: 216-kHz digital audio converter With Stereo ADC and 77 + Routing. 78 + 79 + ti,pcmd3140: Four-channel PDM-input to TDM or I2S output converter. 80 + 81 + ti,pcmd3180: Eight-channel pulse-density-modulation input to TDM or 82 + I2S output converter. 83 + 84 + ti,taa5212: Low-power high-performance stereo audio ADC with 118-dB 85 + dynamic range. 86 + 87 + ti,tad5212: Low-power stereo audio DAC with 120-dB dynamic range. 88 + oneOf: 89 + - items: 90 + - enum: 91 + - ti,adc3120 92 + - ti,adc5120 93 + - ti,pcm3120 94 + - ti,pcm5120 95 + - ti,pcm6120 96 + - const: ti,adc6120 97 + - items: 98 + - enum: 99 + - ti,pcmd512x 100 + - ti,pcm9211 101 + - ti,taa5212 102 + - ti,tad5212 103 + - const: ti,adc6120 104 + - items: 105 + - enum: 106 + - ti,pcm3140 107 + - ti,pcm5140 108 + - ti,dix4192 109 + - ti,pcm6140 110 + - ti,pcm6260 111 + - const: ti,pcm6240 112 + - items: 113 + - enum: 114 + - ti,pcmd3140 115 + - ti,pcmd3180 116 + - ti,pcm1690 117 + - ti,taa5412 118 + - ti,tad5412 119 + - const: ti,pcm6240 120 + - enum: 121 + - ti,adc6120 122 + - ti,pcm6240 123 + 124 + reg: 125 + description: 126 + I2C address, in multiple pcmdevices case, all the i2c address 127 + aggregate as one Audio Device to support multiple audio slots. 128 + minItems: 1 129 + maxItems: 4 130 + 131 + reset-gpios: 132 + maxItems: 1 133 + 134 + interrupts: 135 + maxItems: 1 136 + description: 137 + Invalid only for ti,pcm1690 because of no INT pin. 138 + 139 + '#sound-dai-cells': 140 + const: 0 141 + 142 + required: 143 + - compatible 144 + - reg 145 + 146 + allOf: 147 + - $ref: dai-common.yaml# 148 + - if: 149 + properties: 150 + compatible: 151 + contains: 152 + enum: 153 + - ti,pcm1690 154 + then: 155 + properties: 156 + interrupts: false 157 + 158 + additionalProperties: false 159 + 160 + examples: 161 + - | 162 + #include <dt-bindings/gpio/gpio.h> 163 + i2c { 164 + /* example for two devices with interrupt support */ 165 + #address-cells = <1>; 166 + #size-cells = <0>; 167 + pcm6240: audio-codec@48 { 168 + compatible = "ti,pcm6240"; 169 + reg = <0x48>, /* primary-device */ 170 + <0x4b>; /* secondary-device */ 171 + #sound-dai-cells = <0>; 172 + reset-gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>; 173 + interrupt-parent = <&gpio1>; 174 + interrupts = <15>; 175 + }; 176 + }; 177 + ...
+10
sound/soc/codecs/Kconfig
··· 179 179 imply SND_SOC_PCM5102A 180 180 imply SND_SOC_PCM512x_I2C 181 181 imply SND_SOC_PCM512x_SPI 182 + imply SND_SOC_PCM6240 182 183 imply SND_SOC_PEB2466 183 184 imply SND_SOC_RK3308 184 185 imply SND_SOC_RK3328 ··· 1424 1423 depends on SPI_MASTER 1425 1424 select SND_SOC_PCM512x 1426 1425 select REGMAP_SPI 1426 + 1427 + config SND_SOC_PCM6240 1428 + tristate "Texas Instruments PCM6240 Family Audio chips based on I2C" 1429 + depends on I2C 1430 + help 1431 + Enable support for Texas Instruments PCM6240 Family Audio chips. 1432 + Note the PCM6240 driver implements a flexible and configurable 1433 + setting for register and filter coefficients, to one, two or 1434 + even multiple PCM6240 Family Audio chips. 1427 1435 1428 1436 config SND_SOC_PEB2466 1429 1437 tristate "Infineon PEB2466 quad PCM codec"
+2
sound/soc/codecs/Makefile
··· 204 204 snd-soc-pcm512x-objs := pcm512x.o 205 205 snd-soc-pcm512x-i2c-objs := pcm512x-i2c.o 206 206 snd-soc-pcm512x-spi-objs := pcm512x-spi.o 207 + snd-soc-pcm6240-objs := pcm6240.o 207 208 snd-soc-peb2466-objs := peb2466.o 208 209 snd-soc-rk3308-objs := rk3308_codec.o 209 210 snd-soc-rk3328-objs := rk3328_codec.o ··· 596 595 obj-$(CONFIG_SND_SOC_PCM512x) += snd-soc-pcm512x.o 597 596 obj-$(CONFIG_SND_SOC_PCM512x_I2C) += snd-soc-pcm512x-i2c.o 598 597 obj-$(CONFIG_SND_SOC_PCM512x_SPI) += snd-soc-pcm512x-spi.o 598 + obj-$(CONFIG_SND_SOC_PCM6240) += snd-soc-pcm6240.o 599 599 obj-$(CONFIG_SND_SOC_PEB2466) += snd-soc-peb2466.o 600 600 obj-$(CONFIG_SND_SOC_RK3308) += snd-soc-rk3308.o 601 601 obj-$(CONFIG_SND_SOC_RK3328) += snd-soc-rk3328.o
+2217
sound/soc/codecs/pcm6240.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // 3 + // ALSA SoC Texas Instruments PCM6240 Family Audio ADC/DAC Device 4 + // 5 + // Copyright (C) 2022 - 2024 Texas Instruments Incorporated 6 + // https://www.ti.com 7 + // 8 + // The PCM6240 driver implements a flexible and configurable 9 + // algo coefficient setting for one, two, or even multiple 10 + // PCM6240 Family chips. 11 + // 12 + // Author: Shenghao Ding <shenghao-ding@ti.com> 13 + // 14 + 15 + #include <asm/unaligned.h> 16 + #include <linux/firmware.h> 17 + #include <linux/gpio.h> 18 + #include <linux/i2c.h> 19 + #include <linux/module.h> 20 + #include <linux/of_irq.h> 21 + #include <linux/regmap.h> 22 + #include <sound/pcm_params.h> 23 + #include <sound/soc.h> 24 + #include <sound/tlv.h> 25 + 26 + #include "pcm6240.h" 27 + 28 + static const struct i2c_device_id pcmdevice_i2c_id[] = { 29 + { "adc3120", ADC3120 }, 30 + { "adc5120", ADC5120 }, 31 + { "adc6120", ADC6120 }, 32 + { "dix4192", DIX4192 }, 33 + { "pcm1690", PCM1690 }, 34 + { "pcm3120", PCM3120 }, 35 + { "pcm3140", PCM3140 }, 36 + { "pcm5120", PCM5120 }, 37 + { "pcm5140", PCM5140 }, 38 + { "pcm6120", PCM6120 }, 39 + { "pcm6140", PCM6140 }, 40 + { "pcm6240", PCM6240 }, 41 + { "pcm6260", PCM6260 }, 42 + { "pcm9211", PCM9211 }, 43 + { "pcmd3140", PCMD3140 }, 44 + { "pcmd3180", PCMD3180 }, 45 + { "pcmd512x", PCMD512X }, 46 + { "taa5212", TAA5212 }, 47 + { "taa5412", TAA5412 }, 48 + { "tad5212", TAD5212 }, 49 + { "tad5412", TAD5412 }, 50 + {} 51 + }; 52 + MODULE_DEVICE_TABLE(i2c, pcmdevice_i2c_id); 53 + 54 + static const char *const pcmdev_ctrl_name[] = { 55 + "%s i2c%d Dev%d Ch%d Ana Volume", 56 + "%s i2c%d Dev%d Ch%d Digi Volume", 57 + "%s i2c%d Dev%d Ch%d Fine Volume", 58 + }; 59 + 60 + static const char *const pcmdev_ctrl_name_with_prefix[] = { 61 + "%s Dev%d Ch%d Ana Volume", 62 + "%s Dev%d Ch%d Digi Volume", 63 + "%s Dev%d Ch%d Fine Volume", 64 + }; 65 + 66 + static const struct pcmdevice_mixer_control adc5120_analog_gain_ctl[] = { 67 + { 68 + .shift = 1, 69 + .reg = ADC5120_REG_CH1_ANALOG_GAIN, 70 + .max = 0x54, 71 + .invert = 0, 72 + }, 73 + { 74 + .shift = 1, 75 + .reg = ADC5120_REG_CH2_ANALOG_GAIN, 76 + .max = 0x54, 77 + .invert = 0, 78 + } 79 + }; 80 + 81 + static const struct pcmdevice_mixer_control adc5120_digi_gain_ctl[] = { 82 + { 83 + .shift = 0, 84 + .reg = ADC5120_REG_CH1_DIGITAL_GAIN, 85 + .max = 0xff, 86 + .invert = 0, 87 + }, 88 + { 89 + .shift = 0, 90 + .reg = ADC5120_REG_CH2_DIGITAL_GAIN, 91 + .max = 0xff, 92 + .invert = 0, 93 + } 94 + }; 95 + 96 + static const struct pcmdevice_mixer_control pcm1690_digi_gain_ctl[] = { 97 + { 98 + .shift = 0, 99 + .reg = PCM1690_REG_CH1_DIGITAL_GAIN, 100 + .max = 0xff, 101 + .invert = 0, 102 + }, 103 + { 104 + .shift = 0, 105 + .reg = PCM1690_REG_CH2_DIGITAL_GAIN, 106 + .max = 0xff, 107 + .invert = 0, 108 + }, 109 + { 110 + .shift = 0, 111 + .reg = PCM1690_REG_CH3_DIGITAL_GAIN, 112 + .max = 0xff, 113 + .invert = 0, 114 + }, 115 + { 116 + .shift = 0, 117 + .reg = PCM1690_REG_CH4_DIGITAL_GAIN, 118 + .max = 0xff, 119 + .invert = 0, 120 + }, 121 + { 122 + .shift = 0, 123 + .reg = PCM1690_REG_CH5_DIGITAL_GAIN, 124 + .max = 0xff, 125 + .invert = 0, 126 + }, 127 + { 128 + .shift = 0, 129 + .reg = PCM1690_REG_CH6_DIGITAL_GAIN, 130 + .max = 0xff, 131 + .invert = 0, 132 + }, 133 + { 134 + .shift = 0, 135 + .reg = PCM1690_REG_CH7_DIGITAL_GAIN, 136 + .max = 0xff, 137 + .invert = 0, 138 + }, 139 + { 140 + .shift = 0, 141 + .reg = PCM1690_REG_CH8_DIGITAL_GAIN, 142 + .max = 0xff, 143 + .invert = 0, 144 + } 145 + }; 146 + 147 + static const struct pcmdevice_mixer_control pcm6240_analog_gain_ctl[] = { 148 + { 149 + .shift = 2, 150 + .reg = PCM6240_REG_CH1_ANALOG_GAIN, 151 + .max = 0x42, 152 + .invert = 0, 153 + }, 154 + { 155 + .shift = 2, 156 + .reg = PCM6240_REG_CH2_ANALOG_GAIN, 157 + .max = 0x42, 158 + .invert = 0, 159 + }, 160 + { 161 + .shift = 2, 162 + .reg = PCM6240_REG_CH3_ANALOG_GAIN, 163 + .max = 0x42, 164 + .invert = 0, 165 + }, 166 + { 167 + .shift = 2, 168 + .reg = PCM6240_REG_CH4_ANALOG_GAIN, 169 + .max = 0x42, 170 + .invert = 0, 171 + } 172 + }; 173 + 174 + static const struct pcmdevice_mixer_control pcm6240_digi_gain_ctl[] = { 175 + { 176 + .shift = 0, 177 + .reg = PCM6240_REG_CH1_DIGITAL_GAIN, 178 + .max = 0xff, 179 + .invert = 0, 180 + }, 181 + { 182 + .shift = 0, 183 + .reg = PCM6240_REG_CH2_DIGITAL_GAIN, 184 + .max = 0xff, 185 + .invert = 0, 186 + }, 187 + { 188 + .shift = 0, 189 + .reg = PCM6240_REG_CH3_DIGITAL_GAIN, 190 + .max = 0xff, 191 + .invert = 0, 192 + }, 193 + { 194 + .shift = 0, 195 + .reg = PCM6240_REG_CH4_DIGITAL_GAIN, 196 + .max = 0xff, 197 + .invert = 0, 198 + } 199 + }; 200 + 201 + static const struct pcmdevice_mixer_control pcm6260_analog_gain_ctl[] = { 202 + { 203 + .shift = 2, 204 + .reg = PCM6260_REG_CH1_ANALOG_GAIN, 205 + .max = 0x42, 206 + .invert = 0, 207 + }, 208 + { 209 + .shift = 2, 210 + .reg = PCM6260_REG_CH2_ANALOG_GAIN, 211 + .max = 0x42, 212 + .invert = 0, 213 + }, 214 + { 215 + .shift = 2, 216 + .reg = PCM6260_REG_CH3_ANALOG_GAIN, 217 + .max = 0x42, 218 + .invert = 0, 219 + }, 220 + { 221 + .shift = 2, 222 + .reg = PCM6260_REG_CH4_ANALOG_GAIN, 223 + .max = 0x42, 224 + .invert = 0, 225 + }, 226 + { 227 + .shift = 2, 228 + .reg = PCM6260_REG_CH5_ANALOG_GAIN, 229 + .max = 0x42, 230 + .invert = 0, 231 + }, 232 + { 233 + .shift = 2, 234 + .reg = PCM6260_REG_CH6_ANALOG_GAIN, 235 + .max = 0x42, 236 + .invert = 0, 237 + } 238 + }; 239 + 240 + static const struct pcmdevice_mixer_control pcm6260_digi_gain_ctl[] = { 241 + { 242 + .shift = 0, 243 + .reg = PCM6260_REG_CH1_DIGITAL_GAIN, 244 + .max = 0xff, 245 + .invert = 0, 246 + }, 247 + { 248 + .shift = 0, 249 + .reg = PCM6260_REG_CH2_DIGITAL_GAIN, 250 + .max = 0xff, 251 + .invert = 0, 252 + }, 253 + { 254 + .shift = 0, 255 + .reg = PCM6260_REG_CH3_DIGITAL_GAIN, 256 + .max = 0xff, 257 + .invert = 0, 258 + }, 259 + { 260 + .shift = 0, 261 + .reg = PCM6260_REG_CH4_DIGITAL_GAIN, 262 + .max = 0xff, 263 + .invert = 0, 264 + }, 265 + { 266 + .shift = 0, 267 + .reg = PCM6260_REG_CH5_DIGITAL_GAIN, 268 + .max = 0xff, 269 + .invert = 0, 270 + }, 271 + { 272 + .shift = 0, 273 + .reg = PCM6260_REG_CH6_DIGITAL_GAIN, 274 + .max = 0xff, 275 + .invert = 0, 276 + } 277 + }; 278 + 279 + static const struct pcmdevice_mixer_control pcm9211_digi_gain_ctl[] = { 280 + { 281 + .shift = 0, 282 + .reg = PCM9211_REG_CH1_DIGITAL_GAIN, 283 + .max = 0xff, 284 + .invert = 0, 285 + }, 286 + { 287 + .shift = 0, 288 + .reg = PCM9211_REG_CH2_DIGITAL_GAIN, 289 + .max = 0xff, 290 + .invert = 0, 291 + } 292 + }; 293 + 294 + static const struct pcmdevice_mixer_control pcmd3140_digi_gain_ctl[] = { 295 + { 296 + .shift = 0, 297 + .reg = PCMD3140_REG_CH1_DIGITAL_GAIN, 298 + .max = 0xff, 299 + .invert = 0, 300 + }, 301 + { 302 + .shift = 0, 303 + .reg = PCMD3140_REG_CH2_DIGITAL_GAIN, 304 + .max = 0xff, 305 + .invert = 0, 306 + }, 307 + { 308 + .shift = 0, 309 + .reg = PCMD3140_REG_CH3_DIGITAL_GAIN, 310 + .max = 0xff, 311 + .invert = 0, 312 + }, 313 + { 314 + .shift = 0, 315 + .reg = PCMD3140_REG_CH4_DIGITAL_GAIN, 316 + .max = 0xff, 317 + .invert = 0, 318 + } 319 + }; 320 + 321 + static const struct pcmdevice_mixer_control pcmd3140_fine_gain_ctl[] = { 322 + { 323 + .shift = 4, 324 + .reg = PCMD3140_REG_CH1_FINE_GAIN, 325 + .max = 0xf, 326 + .invert = 0, 327 + }, 328 + { 329 + .shift = 4, 330 + .reg = PCMD3140_REG_CH2_FINE_GAIN, 331 + .max = 0xf, 332 + .invert = 0, 333 + }, 334 + { 335 + .shift = 4, 336 + .reg = PCMD3140_REG_CH3_FINE_GAIN, 337 + .max = 0xf, 338 + .invert = 0, 339 + }, 340 + { 341 + .shift = 4, 342 + .reg = PCMD3140_REG_CH4_FINE_GAIN, 343 + .max = 0xf, 344 + .invert = 0, 345 + } 346 + }; 347 + 348 + static const struct pcmdevice_mixer_control pcmd3180_digi_gain_ctl[] = { 349 + { 350 + .shift = 0, 351 + .reg = PCMD3180_REG_CH1_DIGITAL_GAIN, 352 + .max = 0xff, 353 + .invert = 0, 354 + }, 355 + { 356 + .shift = 0, 357 + .reg = PCMD3180_REG_CH2_DIGITAL_GAIN, 358 + .max = 0xff, 359 + .invert = 0, 360 + }, 361 + { 362 + .shift = 0, 363 + .reg = PCMD3180_REG_CH3_DIGITAL_GAIN, 364 + .max = 0xff, 365 + .invert = 0, 366 + }, 367 + { 368 + .shift = 0, 369 + .reg = PCMD3180_REG_CH4_DIGITAL_GAIN, 370 + .max = 0xff, 371 + .invert = 0, 372 + }, 373 + { 374 + .shift = 0, 375 + .reg = PCMD3180_REG_CH5_DIGITAL_GAIN, 376 + .max = 0xff, 377 + .invert = 0, 378 + }, 379 + { 380 + .shift = 0, 381 + .reg = PCMD3180_REG_CH6_DIGITAL_GAIN, 382 + .max = 0xff, 383 + .invert = 0, 384 + }, 385 + { 386 + .shift = 0, 387 + .reg = PCMD3180_REG_CH7_DIGITAL_GAIN, 388 + .max = 0xff, 389 + .invert = 0, 390 + }, 391 + { 392 + .shift = 0, 393 + .reg = PCMD3180_REG_CH8_DIGITAL_GAIN, 394 + .max = 0xff, 395 + .invert = 0, 396 + } 397 + }; 398 + 399 + static const struct pcmdevice_mixer_control pcmd3180_fine_gain_ctl[] = { 400 + { 401 + .shift = 4, 402 + .reg = PCMD3180_REG_CH1_FINE_GAIN, 403 + .max = 0xf, 404 + .invert = 0, 405 + }, 406 + { 407 + .shift = 4, 408 + .reg = PCMD3180_REG_CH2_FINE_GAIN, 409 + .max = 0xf, 410 + .invert = 0, 411 + }, 412 + { 413 + .shift = 4, 414 + .reg = PCMD3180_REG_CH3_FINE_GAIN, 415 + .max = 0xf, 416 + .invert = 0, 417 + }, 418 + { 419 + .shift = 4, 420 + .reg = PCMD3180_REG_CH4_FINE_GAIN, 421 + .max = 0xf, 422 + .invert = 0, 423 + }, 424 + { 425 + .shift = 4, 426 + .reg = PCMD3180_REG_CH5_FINE_GAIN, 427 + .max = 0xf, 428 + .invert = 0, 429 + }, 430 + { 431 + .shift = 4, 432 + .reg = PCMD3180_REG_CH6_FINE_GAIN, 433 + .max = 0xf, 434 + .invert = 0, 435 + }, 436 + { 437 + .shift = 4, 438 + .reg = PCMD3180_REG_CH7_FINE_GAIN, 439 + .max = 0xf, 440 + .invert = 0, 441 + }, 442 + { 443 + .shift = 4, 444 + .reg = PCMD3180_REG_CH8_FINE_GAIN, 445 + .max = 0xf, 446 + .invert = 0, 447 + } 448 + }; 449 + 450 + static const struct pcmdevice_mixer_control taa5412_digi_vol_ctl[] = { 451 + { 452 + .shift = 0, 453 + .reg = TAA5412_REG_CH1_DIGITAL_VOLUME, 454 + .max = 0xff, 455 + .invert = 0, 456 + }, 457 + { 458 + .shift = 0, 459 + .reg = TAA5412_REG_CH2_DIGITAL_VOLUME, 460 + .max = 0xff, 461 + .invert = 0, 462 + }, 463 + { 464 + .shift = 0, 465 + .reg = TAA5412_REG_CH3_DIGITAL_VOLUME, 466 + .max = 0xff, 467 + .invert = 0, 468 + }, 469 + { 470 + .shift = 0, 471 + .reg = TAA5412_REG_CH4_DIGITAL_VOLUME, 472 + .max = 0xff, 473 + .invert = 0, 474 + } 475 + }; 476 + 477 + static const struct pcmdevice_mixer_control taa5412_fine_gain_ctl[] = { 478 + { 479 + .shift = 4, 480 + .reg = TAA5412_REG_CH1_FINE_GAIN, 481 + .max = 0xf, 482 + .invert = 0, 483 + }, 484 + { 485 + .shift = 4, 486 + .reg = TAA5412_REG_CH2_FINE_GAIN, 487 + .max = 0xf, 488 + .invert = 0, 489 + }, 490 + { 491 + .shift = 4, 492 + .reg = TAA5412_REG_CH3_FINE_GAIN, 493 + .max = 0xf, 494 + .invert = 4, 495 + }, 496 + { 497 + .shift = 0, 498 + .reg = TAA5412_REG_CH4_FINE_GAIN, 499 + .max = 0xf, 500 + .invert = 4, 501 + } 502 + }; 503 + 504 + static const DECLARE_TLV_DB_MINMAX_MUTE(pcmd3140_dig_gain_tlv, 505 + -10000, 2700); 506 + static const DECLARE_TLV_DB_MINMAX_MUTE(pcm1690_fine_dig_gain_tlv, 507 + -12750, 0); 508 + static const DECLARE_TLV_DB_MINMAX_MUTE(pcm1690_dig_gain_tlv, 509 + -25500, 0); 510 + static const DECLARE_TLV_DB_MINMAX_MUTE(pcm9211_dig_gain_tlv, 511 + -11450, 2000); 512 + static const DECLARE_TLV_DB_MINMAX_MUTE(adc5120_fgain_tlv, 513 + -10050, 2700); 514 + static const DECLARE_TLV_DB_LINEAR(adc5120_chgain_tlv, 0, 4200); 515 + static const DECLARE_TLV_DB_MINMAX_MUTE(pcm6260_fgain_tlv, 516 + -10000, 2700); 517 + static const DECLARE_TLV_DB_LINEAR(pcm6260_chgain_tlv, 0, 4200); 518 + static const DECLARE_TLV_DB_MINMAX_MUTE(taa5412_dig_vol_tlv, 519 + -8050, 4700); 520 + static const DECLARE_TLV_DB_LINEAR(taa5412_fine_gain_tlv, 521 + -80, 70); 522 + 523 + static int pcmdev_change_dev(struct pcmdevice_priv *pcm_priv, 524 + unsigned short dev_no) 525 + { 526 + struct i2c_client *client = (struct i2c_client *)pcm_priv->client; 527 + struct regmap *map = pcm_priv->regmap; 528 + int ret; 529 + 530 + if (client->addr == pcm_priv->addr[dev_no]) 531 + return 0; 532 + 533 + client->addr = pcm_priv->addr[dev_no]; 534 + /* All pcmdevices share the same regmap, clear the page 535 + * inside regmap once switching to another pcmdevice. 536 + * Register 0 at any pages inside pcmdevice is the same 537 + * one for page-switching. 538 + */ 539 + ret = regmap_write(map, PCMDEVICE_PAGE_SELECT, 0); 540 + if (ret < 0) 541 + dev_err(pcm_priv->dev, "%s: err = %d\n", __func__, ret); 542 + 543 + return ret; 544 + } 545 + 546 + static int pcmdev_dev_read(struct pcmdevice_priv *pcm_dev, 547 + unsigned int dev_no, unsigned int reg, unsigned int *val) 548 + { 549 + struct regmap *map = pcm_dev->regmap; 550 + int ret; 551 + 552 + if (dev_no >= pcm_dev->ndev) { 553 + dev_err(pcm_dev->dev, "%s: no such channel(%d)\n", __func__, 554 + dev_no); 555 + return -EINVAL; 556 + } 557 + 558 + ret = pcmdev_change_dev(pcm_dev, dev_no); 559 + if (ret < 0) { 560 + dev_err(pcm_dev->dev, "%s: chg dev err = %d\n", __func__, ret); 561 + return ret; 562 + } 563 + 564 + ret = regmap_read(map, reg, val); 565 + if (ret < 0) 566 + dev_err(pcm_dev->dev, "%s: err = %d\n", __func__, ret); 567 + 568 + return ret; 569 + } 570 + 571 + static int pcmdev_dev_update_bits(struct pcmdevice_priv *pcm_dev, 572 + unsigned int dev_no, unsigned int reg, unsigned int mask, 573 + unsigned int value) 574 + { 575 + struct regmap *map = pcm_dev->regmap; 576 + int ret; 577 + 578 + if (dev_no >= pcm_dev->ndev) { 579 + dev_err(pcm_dev->dev, "%s: no such channel(%d)\n", __func__, 580 + dev_no); 581 + return -EINVAL; 582 + } 583 + 584 + ret = pcmdev_change_dev(pcm_dev, dev_no); 585 + if (ret < 0) { 586 + dev_err(pcm_dev->dev, "%s: chg dev err = %d\n", __func__, ret); 587 + return ret; 588 + } 589 + 590 + ret = regmap_update_bits(map, reg, mask, value); 591 + if (ret < 0) 592 + dev_err(pcm_dev->dev, "%s: update_bits err=%d\n", 593 + __func__, ret); 594 + 595 + return ret; 596 + } 597 + 598 + static int pcmdev_get_volsw(struct snd_kcontrol *kcontrol, 599 + struct snd_ctl_elem_value *ucontrol, int vol_ctrl_type) 600 + { 601 + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 602 + struct pcmdevice_priv *pcm_dev = 603 + snd_soc_component_get_drvdata(component); 604 + struct pcmdevice_mixer_control *mc = 605 + (struct pcmdevice_mixer_control *)kcontrol->private_value; 606 + int max = mc->max, ret; 607 + unsigned int mask = BIT(fls(max)) - 1; 608 + unsigned int dev_no = mc->dev_no; 609 + unsigned int shift = mc->shift; 610 + unsigned int reg = mc->reg; 611 + unsigned int val; 612 + 613 + mutex_lock(&pcm_dev->codec_lock); 614 + 615 + if (pcm_dev->chip_id == PCM1690) { 616 + ret = pcmdev_dev_read(pcm_dev, dev_no, PCM1690_REG_MODE_CTRL, 617 + &val); 618 + if (ret) { 619 + dev_err(pcm_dev->dev, "%s: read mode err=%d\n", 620 + __func__, ret); 621 + goto out; 622 + } 623 + val &= PCM1690_REG_MODE_CTRL_DAMS_MSK; 624 + /* Set to wide-range mode, before using vol ctrl. */ 625 + if (!val && vol_ctrl_type == PCMDEV_PCM1690_VOL_CTRL) { 626 + ucontrol->value.integer.value[0] = -25500; 627 + goto out; 628 + } 629 + /* Set to fine mode, before using fine vol ctrl. */ 630 + if (val && vol_ctrl_type == PCMDEV_PCM1690_FINE_VOL_CTRL) { 631 + ucontrol->value.integer.value[0] = -12750; 632 + goto out; 633 + } 634 + } 635 + 636 + ret = pcmdev_dev_read(pcm_dev, dev_no, reg, &val); 637 + if (ret) { 638 + dev_err(pcm_dev->dev, "%s: read err=%d\n", 639 + __func__, ret); 640 + goto out; 641 + } 642 + 643 + val = (val >> shift) & mask; 644 + val = (val > max) ? max : val; 645 + val = mc->invert ? max - val : val; 646 + ucontrol->value.integer.value[0] = val; 647 + out: 648 + mutex_unlock(&pcm_dev->codec_lock); 649 + return ret; 650 + } 651 + 652 + static int pcmdevice_get_volsw(struct snd_kcontrol *kcontrol, 653 + struct snd_ctl_elem_value *ucontrol) 654 + { 655 + return pcmdev_get_volsw(kcontrol, ucontrol, PCMDEV_GENERIC_VOL_CTRL); 656 + } 657 + 658 + static int pcm1690_get_volsw(struct snd_kcontrol *kcontrol, 659 + struct snd_ctl_elem_value *ucontrol) 660 + { 661 + return pcmdev_get_volsw(kcontrol, ucontrol, PCMDEV_PCM1690_VOL_CTRL); 662 + } 663 + 664 + static int pcm1690_get_finevolsw(struct snd_kcontrol *kcontrol, 665 + struct snd_ctl_elem_value *ucontrol) 666 + { 667 + return pcmdev_get_volsw(kcontrol, ucontrol, 668 + PCMDEV_PCM1690_FINE_VOL_CTRL); 669 + } 670 + 671 + static int pcmdev_put_volsw(struct snd_kcontrol *kcontrol, 672 + struct snd_ctl_elem_value *ucontrol, int vol_ctrl_type) 673 + { 674 + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 675 + struct pcmdevice_priv *pcm_dev = 676 + snd_soc_component_get_drvdata(component); 677 + struct pcmdevice_mixer_control *mc = 678 + (struct pcmdevice_mixer_control *)kcontrol->private_value; 679 + int max = mc->max, rc; 680 + unsigned int mask = BIT(fls(max)) - 1; 681 + unsigned int dev_no = mc->dev_no; 682 + unsigned int shift = mc->shift; 683 + unsigned int val, val_mask; 684 + unsigned int reg = mc->reg; 685 + 686 + mutex_lock(&pcm_dev->codec_lock); 687 + val = ucontrol->value.integer.value[0] & mask; 688 + val = (val > max) ? max : val; 689 + val = mc->invert ? max - val : val; 690 + val_mask = mask << shift; 691 + val = val << shift; 692 + 693 + switch (vol_ctrl_type) { 694 + case PCMDEV_PCM1690_VOL_CTRL: 695 + val_mask |= PCM1690_REG_MODE_CTRL_DAMS_MSK; 696 + val |= PCM1690_REG_MODE_CTRL_DAMS_WIDE_RANGE; 697 + break; 698 + case PCMDEV_PCM1690_FINE_VOL_CTRL: 699 + val_mask |= PCM1690_REG_MODE_CTRL_DAMS_MSK; 700 + val |= PCM1690_REG_MODE_CTRL_DAMS_FINE_STEP; 701 + break; 702 + } 703 + 704 + rc = pcmdev_dev_update_bits(pcm_dev, dev_no, reg, val_mask, val); 705 + if (rc < 0) 706 + dev_err(pcm_dev->dev, "%s: update_bits err = %d\n", 707 + __func__, rc); 708 + else 709 + rc = 1; 710 + mutex_unlock(&pcm_dev->codec_lock); 711 + return rc; 712 + } 713 + 714 + static int pcmdevice_put_volsw(struct snd_kcontrol *kcontrol, 715 + struct snd_ctl_elem_value *ucontrol) 716 + { 717 + return pcmdev_put_volsw(kcontrol, ucontrol, PCMDEV_GENERIC_VOL_CTRL); 718 + } 719 + 720 + static int pcm1690_put_volsw(struct snd_kcontrol *kcontrol, 721 + struct snd_ctl_elem_value *ucontrol) 722 + { 723 + return pcmdev_put_volsw(kcontrol, ucontrol, PCMDEV_PCM1690_VOL_CTRL); 724 + } 725 + 726 + static int pcm1690_put_finevolsw(struct snd_kcontrol *kcontrol, 727 + struct snd_ctl_elem_value *ucontrol) 728 + { 729 + return pcmdev_put_volsw(kcontrol, ucontrol, 730 + PCMDEV_PCM1690_FINE_VOL_CTRL); 731 + } 732 + 733 + static const struct pcmdev_ctrl_info pcmdev_gain_ctl_info[][2] = { 734 + // ADC3120 735 + { 736 + { 737 + .gain = adc5120_chgain_tlv, 738 + .pcmdev_ctrl = adc5120_analog_gain_ctl, 739 + .ctrl_array_size = ARRAY_SIZE(adc5120_analog_gain_ctl), 740 + .get = pcmdevice_get_volsw, 741 + .put = pcmdevice_put_volsw, 742 + .pcmdev_ctrl_name_id = 0, 743 + }, 744 + { 745 + .gain = adc5120_fgain_tlv, 746 + .pcmdev_ctrl = adc5120_digi_gain_ctl, 747 + .ctrl_array_size = ARRAY_SIZE(adc5120_digi_gain_ctl), 748 + .get = pcmdevice_get_volsw, 749 + .put = pcmdevice_put_volsw, 750 + .pcmdev_ctrl_name_id = 1, 751 + }, 752 + }, 753 + // ADC5120 754 + { 755 + { 756 + .gain = adc5120_chgain_tlv, 757 + .pcmdev_ctrl = adc5120_analog_gain_ctl, 758 + .ctrl_array_size = ARRAY_SIZE(adc5120_analog_gain_ctl), 759 + .get = pcmdevice_get_volsw, 760 + .put = pcmdevice_put_volsw, 761 + .pcmdev_ctrl_name_id = 0, 762 + }, 763 + { 764 + .gain = adc5120_fgain_tlv, 765 + .pcmdev_ctrl = adc5120_digi_gain_ctl, 766 + .ctrl_array_size = ARRAY_SIZE(adc5120_digi_gain_ctl), 767 + .get = pcmdevice_get_volsw, 768 + .put = pcmdevice_put_volsw, 769 + .pcmdev_ctrl_name_id = 1, 770 + }, 771 + }, 772 + // ADC6120 773 + { 774 + { 775 + .gain = adc5120_chgain_tlv, 776 + .pcmdev_ctrl = adc5120_analog_gain_ctl, 777 + .ctrl_array_size = ARRAY_SIZE(adc5120_analog_gain_ctl), 778 + .get = pcmdevice_get_volsw, 779 + .put = pcmdevice_put_volsw, 780 + .pcmdev_ctrl_name_id = 0, 781 + }, 782 + { 783 + .gain = adc5120_fgain_tlv, 784 + .pcmdev_ctrl = adc5120_digi_gain_ctl, 785 + .ctrl_array_size = ARRAY_SIZE(adc5120_digi_gain_ctl), 786 + .get = pcmdevice_get_volsw, 787 + .put = pcmdevice_put_volsw, 788 + .pcmdev_ctrl_name_id = 1, 789 + }, 790 + }, 791 + // DIX4192 792 + { 793 + { 794 + .ctrl_array_size = 0, 795 + }, 796 + { 797 + .ctrl_array_size = 0, 798 + }, 799 + }, 800 + // PCM1690 801 + { 802 + { 803 + .gain = pcm1690_fine_dig_gain_tlv, 804 + .pcmdev_ctrl = pcm1690_digi_gain_ctl, 805 + .ctrl_array_size = ARRAY_SIZE(pcm1690_digi_gain_ctl), 806 + .get = pcm1690_get_volsw, 807 + .put = pcm1690_put_volsw, 808 + .pcmdev_ctrl_name_id = 1, 809 + }, 810 + { 811 + .gain = pcm1690_dig_gain_tlv, 812 + .pcmdev_ctrl = pcm1690_digi_gain_ctl, 813 + .ctrl_array_size = ARRAY_SIZE(pcm1690_digi_gain_ctl), 814 + .get = pcm1690_get_finevolsw, 815 + .put = pcm1690_put_finevolsw, 816 + .pcmdev_ctrl_name_id = 2, 817 + }, 818 + }, 819 + // PCM3120 820 + { 821 + { 822 + .gain = adc5120_chgain_tlv, 823 + .pcmdev_ctrl = adc5120_analog_gain_ctl, 824 + .ctrl_array_size = ARRAY_SIZE(adc5120_analog_gain_ctl), 825 + .get = pcmdevice_get_volsw, 826 + .put = pcmdevice_put_volsw, 827 + .pcmdev_ctrl_name_id = 0, 828 + }, 829 + { 830 + .gain = adc5120_fgain_tlv, 831 + .pcmdev_ctrl = adc5120_digi_gain_ctl, 832 + .ctrl_array_size = ARRAY_SIZE(adc5120_digi_gain_ctl), 833 + .get = pcmdevice_get_volsw, 834 + .put = pcmdevice_put_volsw, 835 + .pcmdev_ctrl_name_id = 1, 836 + }, 837 + }, 838 + // PCM3140 839 + { 840 + { 841 + .gain = pcm6260_chgain_tlv, 842 + .pcmdev_ctrl = pcm6240_analog_gain_ctl, 843 + .ctrl_array_size = ARRAY_SIZE(pcm6240_analog_gain_ctl), 844 + .get = pcmdevice_get_volsw, 845 + .put = pcmdevice_put_volsw, 846 + .pcmdev_ctrl_name_id = 0, 847 + }, 848 + { 849 + .gain = pcm6260_fgain_tlv, 850 + .pcmdev_ctrl = pcm6240_digi_gain_ctl, 851 + .ctrl_array_size = ARRAY_SIZE(pcm6240_digi_gain_ctl), 852 + .get = pcmdevice_get_volsw, 853 + .put = pcmdevice_put_volsw, 854 + .pcmdev_ctrl_name_id = 1, 855 + }, 856 + }, 857 + // PCM5120 858 + { 859 + { 860 + .gain = adc5120_chgain_tlv, 861 + .pcmdev_ctrl = adc5120_analog_gain_ctl, 862 + .ctrl_array_size = ARRAY_SIZE(adc5120_analog_gain_ctl), 863 + .get = pcmdevice_get_volsw, 864 + .put = pcmdevice_put_volsw, 865 + .pcmdev_ctrl_name_id = 0, 866 + }, 867 + { 868 + .gain = adc5120_fgain_tlv, 869 + .pcmdev_ctrl = adc5120_digi_gain_ctl, 870 + .ctrl_array_size = ARRAY_SIZE(adc5120_digi_gain_ctl), 871 + .get = pcmdevice_get_volsw, 872 + .put = pcmdevice_put_volsw, 873 + .pcmdev_ctrl_name_id = 1, 874 + }, 875 + }, 876 + // PCM5140 877 + { 878 + { 879 + .gain = pcm6260_chgain_tlv, 880 + .pcmdev_ctrl = pcm6240_analog_gain_ctl, 881 + .ctrl_array_size = ARRAY_SIZE(pcm6240_analog_gain_ctl), 882 + .get = pcmdevice_get_volsw, 883 + .put = pcmdevice_put_volsw, 884 + .pcmdev_ctrl_name_id = 0, 885 + }, 886 + { 887 + .gain = pcm6260_fgain_tlv, 888 + .pcmdev_ctrl = pcm6240_digi_gain_ctl, 889 + .ctrl_array_size = ARRAY_SIZE(pcm6240_digi_gain_ctl), 890 + .get = pcmdevice_get_volsw, 891 + .put = pcmdevice_put_volsw, 892 + .pcmdev_ctrl_name_id = 1, 893 + }, 894 + }, 895 + // PCM6120 896 + { 897 + { 898 + .gain = adc5120_chgain_tlv, 899 + .pcmdev_ctrl = adc5120_analog_gain_ctl, 900 + .ctrl_array_size = ARRAY_SIZE(adc5120_analog_gain_ctl), 901 + .get = pcmdevice_get_volsw, 902 + .put = pcmdevice_put_volsw, 903 + .pcmdev_ctrl_name_id = 0, 904 + }, 905 + { 906 + .gain = adc5120_fgain_tlv, 907 + .pcmdev_ctrl = adc5120_digi_gain_ctl, 908 + .ctrl_array_size = ARRAY_SIZE(adc5120_digi_gain_ctl), 909 + .get = pcmdevice_get_volsw, 910 + .put = pcmdevice_put_volsw, 911 + .pcmdev_ctrl_name_id = 1, 912 + }, 913 + }, 914 + // PCM6140 915 + { 916 + { 917 + .gain = pcm6260_chgain_tlv, 918 + .pcmdev_ctrl = pcm6240_analog_gain_ctl, 919 + .ctrl_array_size = ARRAY_SIZE(pcm6240_analog_gain_ctl), 920 + .get = pcmdevice_get_volsw, 921 + .put = pcmdevice_put_volsw, 922 + .pcmdev_ctrl_name_id = 0, 923 + }, 924 + { 925 + .gain = pcm6260_fgain_tlv, 926 + .pcmdev_ctrl = pcm6240_digi_gain_ctl, 927 + .ctrl_array_size = ARRAY_SIZE(pcm6240_digi_gain_ctl), 928 + .get = pcmdevice_get_volsw, 929 + .put = pcmdevice_put_volsw, 930 + .pcmdev_ctrl_name_id = 1, 931 + }, 932 + }, 933 + // PCM6240 934 + { 935 + { 936 + .gain = pcm6260_chgain_tlv, 937 + .pcmdev_ctrl = pcm6240_analog_gain_ctl, 938 + .ctrl_array_size = ARRAY_SIZE(pcm6240_analog_gain_ctl), 939 + .get = pcmdevice_get_volsw, 940 + .put = pcmdevice_put_volsw, 941 + .pcmdev_ctrl_name_id = 0, 942 + }, 943 + { 944 + .gain = pcm6260_fgain_tlv, 945 + .pcmdev_ctrl = pcm6240_digi_gain_ctl, 946 + .ctrl_array_size = ARRAY_SIZE(pcm6240_digi_gain_ctl), 947 + .get = pcmdevice_get_volsw, 948 + .put = pcmdevice_put_volsw, 949 + .pcmdev_ctrl_name_id = 1, 950 + }, 951 + }, 952 + // PCM6260 953 + { 954 + { 955 + .gain = pcm6260_chgain_tlv, 956 + .pcmdev_ctrl = pcm6260_analog_gain_ctl, 957 + .ctrl_array_size = ARRAY_SIZE(pcm6260_analog_gain_ctl), 958 + .get = pcmdevice_get_volsw, 959 + .put = pcmdevice_put_volsw, 960 + .pcmdev_ctrl_name_id = 0, 961 + }, 962 + { 963 + .gain = pcm6260_fgain_tlv, 964 + .pcmdev_ctrl = pcm6260_digi_gain_ctl, 965 + .ctrl_array_size = ARRAY_SIZE(pcm6260_digi_gain_ctl), 966 + .get = pcmdevice_get_volsw, 967 + .put = pcmdevice_put_volsw, 968 + .pcmdev_ctrl_name_id = 1, 969 + }, 970 + }, 971 + // PCM9211 972 + { 973 + { 974 + .ctrl_array_size = 0, 975 + }, 976 + { 977 + .gain = pcm9211_dig_gain_tlv, 978 + .pcmdev_ctrl = pcm9211_digi_gain_ctl, 979 + .ctrl_array_size = ARRAY_SIZE(pcm9211_digi_gain_ctl), 980 + .get = pcmdevice_get_volsw, 981 + .put = pcmdevice_put_volsw, 982 + .pcmdev_ctrl_name_id = 1, 983 + }, 984 + 985 + }, 986 + // PCMD3140 987 + { 988 + { 989 + .gain = taa5412_fine_gain_tlv, 990 + .pcmdev_ctrl = pcmd3140_fine_gain_ctl, 991 + .ctrl_array_size = ARRAY_SIZE(pcmd3140_fine_gain_ctl), 992 + .get = pcmdevice_get_volsw, 993 + .put = pcmdevice_put_volsw, 994 + .pcmdev_ctrl_name_id = 2, 995 + }, 996 + { 997 + .gain = pcmd3140_dig_gain_tlv, 998 + .pcmdev_ctrl = pcmd3140_digi_gain_ctl, 999 + .ctrl_array_size = ARRAY_SIZE(pcmd3140_digi_gain_ctl), 1000 + .get = pcmdevice_get_volsw, 1001 + .put = pcmdevice_put_volsw, 1002 + .pcmdev_ctrl_name_id = 1, 1003 + }, 1004 + }, 1005 + // PCMD3180 1006 + { 1007 + { 1008 + .gain = taa5412_fine_gain_tlv, 1009 + .pcmdev_ctrl = pcmd3180_fine_gain_ctl, 1010 + .ctrl_array_size = ARRAY_SIZE(pcmd3180_fine_gain_ctl), 1011 + .get = pcmdevice_get_volsw, 1012 + .put = pcmdevice_put_volsw, 1013 + .pcmdev_ctrl_name_id = 2, 1014 + }, 1015 + { 1016 + .gain = pcmd3140_dig_gain_tlv, 1017 + .pcmdev_ctrl = pcmd3180_digi_gain_ctl, 1018 + .ctrl_array_size = ARRAY_SIZE(pcmd3180_digi_gain_ctl), 1019 + .get = pcmdevice_get_volsw, 1020 + .put = pcmdevice_put_volsw, 1021 + .pcmdev_ctrl_name_id = 1, 1022 + }, 1023 + }, 1024 + // PCMD512X 1025 + { 1026 + { 1027 + .ctrl_array_size = 0, 1028 + }, 1029 + { 1030 + .ctrl_array_size = 0, 1031 + }, 1032 + }, 1033 + // TAA5212 1034 + { 1035 + { 1036 + .gain = taa5412_fine_gain_tlv, 1037 + .pcmdev_ctrl = taa5412_fine_gain_ctl, 1038 + .ctrl_array_size = ARRAY_SIZE(taa5412_fine_gain_ctl), 1039 + .get = pcmdevice_get_volsw, 1040 + .put = pcmdevice_put_volsw, 1041 + .pcmdev_ctrl_name_id = 2, 1042 + }, 1043 + { 1044 + .gain = taa5412_dig_vol_tlv, 1045 + .pcmdev_ctrl = taa5412_digi_vol_ctl, 1046 + .ctrl_array_size = ARRAY_SIZE(taa5412_digi_vol_ctl), 1047 + .get = pcmdevice_get_volsw, 1048 + .put = pcmdevice_put_volsw, 1049 + .pcmdev_ctrl_name_id = 1, 1050 + }, 1051 + }, 1052 + // TAA5412 1053 + { 1054 + { 1055 + .gain = taa5412_fine_gain_tlv, 1056 + .pcmdev_ctrl = taa5412_fine_gain_ctl, 1057 + .ctrl_array_size = ARRAY_SIZE(taa5412_fine_gain_ctl), 1058 + .get = pcmdevice_get_volsw, 1059 + .put = pcmdevice_put_volsw, 1060 + .pcmdev_ctrl_name_id = 2, 1061 + }, 1062 + { 1063 + .gain = taa5412_dig_vol_tlv, 1064 + .pcmdev_ctrl = taa5412_digi_vol_ctl, 1065 + .ctrl_array_size = ARRAY_SIZE(taa5412_digi_vol_ctl), 1066 + .get = pcmdevice_get_volsw, 1067 + .put = pcmdevice_put_volsw, 1068 + .pcmdev_ctrl_name_id = 1, 1069 + }, 1070 + }, 1071 + // TAD5212 1072 + { 1073 + { 1074 + .ctrl_array_size = 0, 1075 + }, 1076 + { 1077 + .ctrl_array_size = 0, 1078 + }, 1079 + }, 1080 + // TAD5412 1081 + { 1082 + { 1083 + .ctrl_array_size = 0, 1084 + }, 1085 + { 1086 + .ctrl_array_size = 0, 1087 + }, 1088 + }, 1089 + }; 1090 + 1091 + static int pcmdev_dev_bulk_write(struct pcmdevice_priv *pcm_dev, 1092 + unsigned int dev_no, unsigned int reg, unsigned char *data, 1093 + unsigned int len) 1094 + { 1095 + struct regmap *map = pcm_dev->regmap; 1096 + int ret; 1097 + 1098 + if (dev_no >= pcm_dev->ndev) { 1099 + dev_err(pcm_dev->dev, "%s: no such channel(%d)\n", __func__, 1100 + dev_no); 1101 + return -EINVAL; 1102 + } 1103 + 1104 + ret = pcmdev_change_dev(pcm_dev, dev_no); 1105 + if (ret < 0) { 1106 + dev_err(pcm_dev->dev, "%s: chg dev err = %d\n", __func__, ret); 1107 + return ret; 1108 + } 1109 + 1110 + ret = regmap_bulk_write(map, reg, data, len); 1111 + if (ret < 0) 1112 + dev_err(pcm_dev->dev, "%s: bulk_write err = %d\n", __func__, 1113 + ret); 1114 + 1115 + return ret; 1116 + } 1117 + 1118 + static int pcmdev_dev_write(struct pcmdevice_priv *pcm_dev, 1119 + unsigned int dev_no, unsigned int reg, unsigned int value) 1120 + { 1121 + struct regmap *map = pcm_dev->regmap; 1122 + int ret; 1123 + 1124 + if (dev_no >= pcm_dev->ndev) { 1125 + dev_err(pcm_dev->dev, "%s: no such channel(%d)\n", __func__, 1126 + dev_no); 1127 + return -EINVAL; 1128 + } 1129 + 1130 + ret = pcmdev_change_dev(pcm_dev, dev_no); 1131 + if (ret < 0) { 1132 + dev_err(pcm_dev->dev, "%s: chg dev err = %d\n", __func__, ret); 1133 + return ret; 1134 + } 1135 + 1136 + ret = regmap_write(map, reg, value); 1137 + if (ret < 0) 1138 + dev_err(pcm_dev->dev, "%s: err = %d\n", __func__, ret); 1139 + 1140 + return ret; 1141 + } 1142 + 1143 + static int pcmdevice_info_profile( 1144 + struct snd_kcontrol *kcontrol, 1145 + struct snd_ctl_elem_info *uinfo) 1146 + { 1147 + struct snd_soc_component *codec 1148 + = snd_soc_kcontrol_component(kcontrol); 1149 + struct pcmdevice_priv *pcm_dev = 1150 + snd_soc_component_get_drvdata(codec); 1151 + 1152 + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 1153 + uinfo->count = 1; 1154 + uinfo->value.integer.min = 0; 1155 + uinfo->value.integer.max = max(0, pcm_dev->regbin.ncfgs - 1); 1156 + 1157 + return 0; 1158 + } 1159 + 1160 + static int pcmdevice_get_profile_id( 1161 + struct snd_kcontrol *kcontrol, 1162 + struct snd_ctl_elem_value *ucontrol) 1163 + { 1164 + struct snd_soc_component *codec 1165 + = snd_soc_kcontrol_component(kcontrol); 1166 + struct pcmdevice_priv *pcm_dev = 1167 + snd_soc_component_get_drvdata(codec); 1168 + 1169 + ucontrol->value.integer.value[0] = pcm_dev->cur_conf; 1170 + 1171 + return 0; 1172 + } 1173 + 1174 + static int pcmdevice_set_profile_id( 1175 + struct snd_kcontrol *kcontrol, 1176 + struct snd_ctl_elem_value *ucontrol) 1177 + { 1178 + struct snd_soc_component *codec 1179 + = snd_soc_kcontrol_component(kcontrol); 1180 + struct pcmdevice_priv *pcm_dev = 1181 + snd_soc_component_get_drvdata(codec); 1182 + int nr_profile = ucontrol->value.integer.value[0]; 1183 + int max = pcm_dev->regbin.ncfgs - 1; 1184 + int ret = 0; 1185 + 1186 + nr_profile = clamp(nr_profile, 0, max); 1187 + 1188 + if (pcm_dev->cur_conf != nr_profile) { 1189 + pcm_dev->cur_conf = nr_profile; 1190 + ret = 1; 1191 + } 1192 + 1193 + return ret; 1194 + } 1195 + 1196 + static int pcmdevice_info_volsw(struct snd_kcontrol *kcontrol, 1197 + struct snd_ctl_elem_info *uinfo) 1198 + { 1199 + struct pcmdevice_mixer_control *mc = 1200 + (struct pcmdevice_mixer_control *)kcontrol->private_value; 1201 + 1202 + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 1203 + uinfo->count = 1; 1204 + uinfo->value.integer.min = 0; 1205 + uinfo->value.integer.max = mc->max; 1206 + return 0; 1207 + } 1208 + 1209 + static void pcm9211_sw_rst(struct pcmdevice_priv *pcm_dev) 1210 + { 1211 + int ret, i; 1212 + 1213 + for (i = 0; i < pcm_dev->ndev; i++) { 1214 + ret = pcmdev_dev_update_bits(pcm_dev, i, 1215 + PCM9211_REG_SW_CTRL, PCM9211_REG_SW_CTRL_MRST_MSK, 1216 + PCM9211_REG_SW_CTRL_MRST); 1217 + if (ret < 0) 1218 + dev_err(pcm_dev->dev, "%s: dev %d swreset fail %d\n", 1219 + __func__, i, ret); 1220 + } 1221 + } 1222 + 1223 + static void pcmdevice_sw_rst(struct pcmdevice_priv *pcm_dev) 1224 + { 1225 + int ret, i; 1226 + 1227 + for (i = 0; i < pcm_dev->ndev; i++) { 1228 + ret = pcmdev_dev_write(pcm_dev, i, PCMDEVICE_REG_SWRESET, 1229 + PCMDEVICE_REG_SWRESET_RESET); 1230 + if (ret < 0) 1231 + dev_err(pcm_dev->dev, "%s: dev %d swreset fail %d\n", 1232 + __func__, i, ret); 1233 + } 1234 + } 1235 + 1236 + static struct pcmdevice_config_info *pcmdevice_add_config(void *ctxt, 1237 + const unsigned char *config_data, unsigned int config_size, 1238 + int *status) 1239 + { 1240 + struct pcmdevice_priv *pcm_dev = (struct pcmdevice_priv *)ctxt; 1241 + struct pcmdevice_config_info *cfg_info; 1242 + struct pcmdevice_block_data **bk_da; 1243 + unsigned int config_offset = 0, i; 1244 + 1245 + cfg_info = kzalloc(sizeof(struct pcmdevice_config_info), GFP_KERNEL); 1246 + if (!cfg_info) { 1247 + *status = -ENOMEM; 1248 + goto out; 1249 + } 1250 + 1251 + if (pcm_dev->regbin.fw_hdr.binary_version_num >= 0x105) { 1252 + if (config_offset + 64 > (int)config_size) { 1253 + *status = -EINVAL; 1254 + dev_err(pcm_dev->dev, 1255 + "%s: cfg_name out of boundary\n", __func__); 1256 + goto out; 1257 + } 1258 + memcpy(cfg_info->cfg_name, &config_data[config_offset], 64); 1259 + config_offset += 64; 1260 + } 1261 + 1262 + if (config_offset + 4 > config_size) { 1263 + *status = -EINVAL; 1264 + dev_err(pcm_dev->dev, "%s: nblocks out of boundary\n", 1265 + __func__); 1266 + goto out; 1267 + } 1268 + cfg_info->nblocks = 1269 + get_unaligned_be32(&config_data[config_offset]); 1270 + config_offset += 4; 1271 + 1272 + bk_da = cfg_info->blk_data = kcalloc(cfg_info->nblocks, 1273 + sizeof(struct pcmdevice_block_data *), GFP_KERNEL); 1274 + if (!bk_da) { 1275 + *status = -ENOMEM; 1276 + goto out; 1277 + } 1278 + cfg_info->real_nblocks = 0; 1279 + for (i = 0; i < cfg_info->nblocks; i++) { 1280 + if (config_offset + 12 > config_size) { 1281 + *status = -EINVAL; 1282 + dev_err(pcm_dev->dev, 1283 + "%s: out of boundary i = %d nblocks = %u\n", 1284 + __func__, i, cfg_info->nblocks); 1285 + break; 1286 + } 1287 + bk_da[i] = kzalloc(sizeof(struct pcmdevice_block_data), 1288 + GFP_KERNEL); 1289 + if (!bk_da[i]) { 1290 + *status = -ENOMEM; 1291 + break; 1292 + } 1293 + bk_da[i]->dev_idx = config_data[config_offset]; 1294 + config_offset++; 1295 + 1296 + bk_da[i]->block_type = config_data[config_offset]; 1297 + config_offset++; 1298 + 1299 + if (bk_da[i]->block_type == PCMDEVICE_BIN_BLK_PRE_POWER_UP) { 1300 + if (bk_da[i]->dev_idx == 0) 1301 + cfg_info->active_dev = 1302 + (1 << pcm_dev->ndev) - 1; 1303 + else 1304 + cfg_info->active_dev = 1305 + 1 << (bk_da[i]->dev_idx - 1); 1306 + } 1307 + 1308 + bk_da[i]->yram_checksum = 1309 + get_unaligned_be16(&config_data[config_offset]); 1310 + config_offset += 2; 1311 + bk_da[i]->block_size = 1312 + get_unaligned_be32(&config_data[config_offset]); 1313 + config_offset += 4; 1314 + 1315 + bk_da[i]->n_subblks = 1316 + get_unaligned_be32(&config_data[config_offset]); 1317 + 1318 + config_offset += 4; 1319 + 1320 + if (config_offset + bk_da[i]->block_size > config_size) { 1321 + *status = -EINVAL; 1322 + dev_err(pcm_dev->dev, 1323 + "%s: out of boundary: i = %d blks = %u\n", 1324 + __func__, i, cfg_info->nblocks); 1325 + break; 1326 + } 1327 + 1328 + bk_da[i]->regdata = kmemdup(&config_data[config_offset], 1329 + bk_da[i]->block_size, GFP_KERNEL); 1330 + if (!bk_da[i]->regdata) { 1331 + *status = -ENOMEM; 1332 + goto out; 1333 + } 1334 + config_offset += bk_da[i]->block_size; 1335 + cfg_info->real_nblocks += 1; 1336 + } 1337 + out: 1338 + return cfg_info; 1339 + } 1340 + 1341 + static int pcmdev_gain_ctrl_add(struct pcmdevice_priv *pcm_dev, 1342 + int dev_no, int ctl_id) 1343 + { 1344 + struct i2c_adapter *adap = pcm_dev->client->adapter; 1345 + struct snd_soc_component *comp = pcm_dev->component; 1346 + struct pcmdevice_mixer_control *pcmdev_ctrl; 1347 + struct snd_kcontrol_new *pcmdev_controls; 1348 + int ret, mix_index = 0, name_id, chn; 1349 + unsigned int id = pcm_dev->chip_id; 1350 + const int nr_chn = 1351 + pcmdev_gain_ctl_info[id][ctl_id].ctrl_array_size; 1352 + const char *ctrl_name; 1353 + char *name; 1354 + 1355 + if (!nr_chn) { 1356 + dev_dbg(pcm_dev->dev, "%s: no gain ctrl for %s\n", __func__, 1357 + pcm_dev->dev_name); 1358 + return 0; 1359 + } 1360 + 1361 + pcmdev_controls = devm_kzalloc(pcm_dev->dev, 1362 + nr_chn * sizeof(struct snd_kcontrol_new), GFP_KERNEL); 1363 + if (!pcmdev_controls) 1364 + return -ENOMEM; 1365 + 1366 + name_id = pcmdev_gain_ctl_info[id][ctl_id].pcmdev_ctrl_name_id; 1367 + 1368 + if (comp->name_prefix) 1369 + ctrl_name = pcmdev_ctrl_name_with_prefix[name_id]; 1370 + else 1371 + ctrl_name = pcmdev_ctrl_name[name_id]; 1372 + 1373 + for (chn = 1; chn <= nr_chn; chn++) { 1374 + name = devm_kzalloc(pcm_dev->dev, 1375 + SNDRV_CTL_ELEM_ID_NAME_MAXLEN, GFP_KERNEL); 1376 + if (!name) { 1377 + ret = -ENOMEM; 1378 + goto out; 1379 + } 1380 + if (comp->name_prefix) 1381 + scnprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, 1382 + ctrl_name, comp->name_prefix, dev_no, chn); 1383 + else 1384 + scnprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, 1385 + ctrl_name, pcm_dev->upper_dev_name, adap->nr, 1386 + dev_no, chn); 1387 + pcmdev_controls[mix_index].tlv.p = 1388 + pcmdev_gain_ctl_info[id][ctl_id].gain; 1389 + pcmdev_ctrl = devm_kmemdup(pcm_dev->dev, 1390 + &pcmdev_gain_ctl_info[id][ctl_id].pcmdev_ctrl[chn - 1], 1391 + sizeof(*pcmdev_ctrl), GFP_KERNEL); 1392 + if (!pcmdev_ctrl) { 1393 + ret = -ENOMEM; 1394 + goto out; 1395 + } 1396 + pcmdev_ctrl->dev_no = dev_no; 1397 + pcmdev_controls[mix_index].private_value = 1398 + (unsigned long)pcmdev_ctrl; 1399 + pcmdev_controls[mix_index].name = name; 1400 + pcmdev_controls[mix_index].access = 1401 + SNDRV_CTL_ELEM_ACCESS_TLV_READ | 1402 + SNDRV_CTL_ELEM_ACCESS_READWRITE; 1403 + pcmdev_controls[mix_index].iface = 1404 + SNDRV_CTL_ELEM_IFACE_MIXER; 1405 + pcmdev_controls[mix_index].info = pcmdevice_info_volsw; 1406 + pcmdev_controls[mix_index].get = 1407 + pcmdev_gain_ctl_info[id][ctl_id].get; 1408 + pcmdev_controls[mix_index].put = 1409 + pcmdev_gain_ctl_info[id][ctl_id].put; 1410 + mix_index++; 1411 + } 1412 + 1413 + ret = snd_soc_add_component_controls(comp, pcmdev_controls, mix_index); 1414 + if (ret) 1415 + dev_err(pcm_dev->dev, "%s: add_controls err = %d\n", 1416 + __func__, ret); 1417 + out: 1418 + return ret; 1419 + } 1420 + 1421 + static int pcmdev_profile_ctrl_add(struct pcmdevice_priv *pcm_dev) 1422 + { 1423 + struct snd_soc_component *comp = pcm_dev->component; 1424 + struct i2c_adapter *adap = pcm_dev->client->adapter; 1425 + struct snd_kcontrol_new *pcmdev_ctrl; 1426 + char *name; 1427 + int ret; 1428 + 1429 + pcmdev_ctrl = devm_kzalloc(pcm_dev->dev, 1430 + sizeof(struct snd_kcontrol_new), GFP_KERNEL); 1431 + if (!pcmdev_ctrl) 1432 + return -ENOMEM; 1433 + 1434 + /* Create a mixer item for selecting the active profile */ 1435 + name = devm_kzalloc(pcm_dev->dev, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, 1436 + GFP_KERNEL); 1437 + if (!name) 1438 + return -ENOMEM; 1439 + 1440 + if (comp->name_prefix) 1441 + scnprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, 1442 + "%s Profile id", comp->name_prefix); 1443 + else 1444 + scnprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, 1445 + "%s i2c%d Profile id", pcm_dev->upper_dev_name, 1446 + adap->nr); 1447 + pcmdev_ctrl->name = name; 1448 + pcmdev_ctrl->iface = SNDRV_CTL_ELEM_IFACE_MIXER; 1449 + pcmdev_ctrl->info = pcmdevice_info_profile; 1450 + pcmdev_ctrl->get = pcmdevice_get_profile_id; 1451 + pcmdev_ctrl->put = pcmdevice_set_profile_id; 1452 + 1453 + ret = snd_soc_add_component_controls(comp, pcmdev_ctrl, 1); 1454 + if (ret) 1455 + dev_err(pcm_dev->dev, "%s: add_controls err = %d\n", 1456 + __func__, ret); 1457 + 1458 + return ret; 1459 + } 1460 + 1461 + static void pcmdevice_config_info_remove(void *ctxt) 1462 + { 1463 + struct pcmdevice_priv *pcm_dev = (struct pcmdevice_priv *) ctxt; 1464 + struct pcmdevice_regbin *regbin = &(pcm_dev->regbin); 1465 + struct pcmdevice_config_info **cfg_info = regbin->cfg_info; 1466 + int i, j; 1467 + 1468 + if (!cfg_info) 1469 + return; 1470 + for (i = 0; i < regbin->ncfgs; i++) { 1471 + if (!cfg_info[i]) 1472 + continue; 1473 + if (cfg_info[i]->blk_data) { 1474 + for (j = 0; j < (int)cfg_info[i]->real_nblocks; j++) { 1475 + if (!cfg_info[i]->blk_data[j]) 1476 + continue; 1477 + kfree(cfg_info[i]->blk_data[j]->regdata); 1478 + kfree(cfg_info[i]->blk_data[j]); 1479 + } 1480 + kfree(cfg_info[i]->blk_data); 1481 + } 1482 + kfree(cfg_info[i]); 1483 + } 1484 + kfree(cfg_info); 1485 + } 1486 + 1487 + static int pcmdev_regbin_ready(const struct firmware *fmw, void *ctxt) 1488 + { 1489 + struct pcmdevice_config_info **cfg_info; 1490 + struct pcmdevice_priv *pcm_dev = ctxt; 1491 + struct pcmdevice_regbin_hdr *fw_hdr; 1492 + struct pcmdevice_regbin *regbin; 1493 + unsigned int total_config_sz = 0; 1494 + int offset = 0, ret = 0, i; 1495 + unsigned char *buf; 1496 + 1497 + regbin = &(pcm_dev->regbin); 1498 + fw_hdr = &(regbin->fw_hdr); 1499 + if (!fmw || !fmw->data) { 1500 + dev_err(pcm_dev->dev, "%s: failed to read %s\n", 1501 + __func__, pcm_dev->bin_name); 1502 + pcm_dev->fw_state = PCMDEVICE_FW_LOAD_FAILED; 1503 + ret = -EINVAL; 1504 + goto out; 1505 + } 1506 + buf = (unsigned char *)fmw->data; 1507 + 1508 + fw_hdr->img_sz = get_unaligned_be32(&buf[offset]); 1509 + offset += 4; 1510 + if (fw_hdr->img_sz != fmw->size) { 1511 + dev_err(pcm_dev->dev, "%s: file size(%d) not match %u", 1512 + __func__, (int)fmw->size, fw_hdr->img_sz); 1513 + pcm_dev->fw_state = PCMDEVICE_FW_LOAD_FAILED; 1514 + ret = -EINVAL; 1515 + goto out; 1516 + } 1517 + 1518 + fw_hdr->checksum = get_unaligned_be32(&buf[offset]); 1519 + offset += 4; 1520 + fw_hdr->binary_version_num = get_unaligned_be32(&buf[offset]); 1521 + if (fw_hdr->binary_version_num < 0x103) { 1522 + dev_err(pcm_dev->dev, "%s: bin version 0x%04x is out of date", 1523 + __func__, fw_hdr->binary_version_num); 1524 + pcm_dev->fw_state = PCMDEVICE_FW_LOAD_FAILED; 1525 + ret = -EINVAL; 1526 + goto out; 1527 + } 1528 + offset += 4; 1529 + fw_hdr->drv_fw_version = get_unaligned_be32(&buf[offset]); 1530 + offset += 8; 1531 + fw_hdr->plat_type = buf[offset]; 1532 + offset += 1; 1533 + fw_hdr->dev_family = buf[offset]; 1534 + offset += 1; 1535 + fw_hdr->reserve = buf[offset]; 1536 + offset += 1; 1537 + fw_hdr->ndev = buf[offset]; 1538 + offset += 1; 1539 + if (fw_hdr->ndev != pcm_dev->ndev) { 1540 + dev_err(pcm_dev->dev, "%s: invalid ndev(%u)\n", __func__, 1541 + fw_hdr->ndev); 1542 + pcm_dev->fw_state = PCMDEVICE_FW_LOAD_FAILED; 1543 + ret = -EINVAL; 1544 + goto out; 1545 + } 1546 + 1547 + if (offset + PCMDEVICE_MAX_REGBIN_DEVICES > fw_hdr->img_sz) { 1548 + dev_err(pcm_dev->dev, "%s: devs out of boundary!\n", __func__); 1549 + pcm_dev->fw_state = PCMDEVICE_FW_LOAD_FAILED; 1550 + ret = -EINVAL; 1551 + goto out; 1552 + } 1553 + 1554 + for (i = 0; i < PCMDEVICE_MAX_REGBIN_DEVICES; i++, offset++) 1555 + fw_hdr->devs[i] = buf[offset]; 1556 + 1557 + fw_hdr->nconfig = get_unaligned_be32(&buf[offset]); 1558 + offset += 4; 1559 + 1560 + for (i = 0; i < PCMDEVICE_CONFIG_SUM; i++) { 1561 + fw_hdr->config_size[i] = get_unaligned_be32(&buf[offset]); 1562 + offset += 4; 1563 + total_config_sz += fw_hdr->config_size[i]; 1564 + } 1565 + 1566 + if (fw_hdr->img_sz - total_config_sz != (unsigned int)offset) { 1567 + dev_err(pcm_dev->dev, "%s: bin file error!\n", __func__); 1568 + pcm_dev->fw_state = PCMDEVICE_FW_LOAD_FAILED; 1569 + ret = -EINVAL; 1570 + goto out; 1571 + } 1572 + cfg_info = kcalloc(fw_hdr->nconfig, sizeof(*cfg_info), GFP_KERNEL); 1573 + if (!cfg_info) { 1574 + pcm_dev->fw_state = PCMDEVICE_FW_LOAD_FAILED; 1575 + ret = -ENOMEM; 1576 + goto out; 1577 + } 1578 + regbin->cfg_info = cfg_info; 1579 + regbin->ncfgs = 0; 1580 + for (i = 0; i < (int)fw_hdr->nconfig; i++) { 1581 + cfg_info[i] = pcmdevice_add_config(ctxt, &buf[offset], 1582 + fw_hdr->config_size[i], &ret); 1583 + if (ret) { 1584 + /* In case the bin file is partially destroyed. */ 1585 + if (regbin->ncfgs == 0) 1586 + pcm_dev->fw_state = PCMDEVICE_FW_LOAD_FAILED; 1587 + break; 1588 + } 1589 + offset += (int)fw_hdr->config_size[i]; 1590 + regbin->ncfgs += 1; 1591 + } 1592 + 1593 + out: 1594 + if (pcm_dev->fw_state == PCMDEVICE_FW_LOAD_FAILED) { 1595 + dev_err(pcm_dev->dev, 1596 + "%s: remove config due to fw load error!\n", __func__); 1597 + pcmdevice_config_info_remove(pcm_dev); 1598 + } 1599 + 1600 + return ret; 1601 + } 1602 + 1603 + static int pcmdevice_comp_probe(struct snd_soc_component *comp) 1604 + { 1605 + struct pcmdevice_priv *pcm_dev = snd_soc_component_get_drvdata(comp); 1606 + struct i2c_adapter *adap = pcm_dev->client->adapter; 1607 + const struct firmware *fw_entry = NULL; 1608 + int ret, i, j; 1609 + 1610 + mutex_lock(&pcm_dev->codec_lock); 1611 + 1612 + pcm_dev->component = comp; 1613 + 1614 + for (i = 0; i < pcm_dev->ndev; i++) { 1615 + for (j = 0; j < 2; j++) { 1616 + ret = pcmdev_gain_ctrl_add(pcm_dev, i, j); 1617 + if (ret < 0) 1618 + goto out; 1619 + } 1620 + } 1621 + 1622 + if (comp->name_prefix) { 1623 + /* There's name_prefix defined in DTS. Bin file name will be 1624 + * name_prefix.bin stores the firmware including register 1625 + * setting and params for different filters inside chips, it 1626 + * must be copied into firmware folder. The same types of 1627 + * pcmdevices sitting on the same i2c bus will be aggregated as 1628 + * one single codec, all of them share the same bin file. 1629 + */ 1630 + scnprintf(pcm_dev->bin_name, PCMDEVICE_BIN_FILENAME_LEN, 1631 + "%s.bin", comp->name_prefix); 1632 + } else { 1633 + /* There's NO name_prefix defined in DTS. Bin file name will be 1634 + * device-name[defined in pcmdevice_i2c_id]-i2c-bus_id 1635 + * [0,1,...,N]-sum[1,...,4]dev.bin stores the firmware 1636 + * including register setting and params for different filters 1637 + * inside chips, it must be copied into firmware folder. The 1638 + * same types of pcmdevices sitting on the same i2c bus will be 1639 + * aggregated as one single codec, all of them share the same 1640 + * bin file. 1641 + */ 1642 + scnprintf(pcm_dev->bin_name, PCMDEVICE_BIN_FILENAME_LEN, 1643 + "%s-i2c-%d-%udev.bin", pcm_dev->dev_name, adap->nr, 1644 + pcm_dev->ndev); 1645 + } 1646 + 1647 + ret = request_firmware(&fw_entry, pcm_dev->bin_name, pcm_dev->dev); 1648 + if (ret) { 1649 + dev_err(pcm_dev->dev, "%s: request %s err = %d\n", __func__, 1650 + pcm_dev->bin_name, ret); 1651 + goto out; 1652 + } 1653 + 1654 + ret = pcmdev_regbin_ready(fw_entry, pcm_dev); 1655 + if (ret) { 1656 + dev_err(pcm_dev->dev, "%s: %s parse err = %d\n", __func__, 1657 + pcm_dev->bin_name, ret); 1658 + goto out; 1659 + } 1660 + ret = pcmdev_profile_ctrl_add(pcm_dev); 1661 + out: 1662 + if (fw_entry) 1663 + release_firmware(fw_entry); 1664 + 1665 + mutex_unlock(&pcm_dev->codec_lock); 1666 + return ret; 1667 + } 1668 + 1669 + 1670 + static void pcmdevice_comp_remove(struct snd_soc_component *codec) 1671 + { 1672 + struct pcmdevice_priv *pcm_dev = snd_soc_component_get_drvdata(codec); 1673 + 1674 + if (!pcm_dev) 1675 + return; 1676 + mutex_lock(&pcm_dev->codec_lock); 1677 + pcmdevice_config_info_remove(pcm_dev); 1678 + mutex_unlock(&pcm_dev->codec_lock); 1679 + } 1680 + 1681 + static const struct snd_soc_dapm_widget pcmdevice_dapm_widgets[] = { 1682 + SND_SOC_DAPM_AIF_IN("ASI", "ASI Playback", 0, SND_SOC_NOPM, 0, 0), 1683 + SND_SOC_DAPM_AIF_OUT("ASI1 OUT", "ASI1 Capture", 1684 + 0, SND_SOC_NOPM, 0, 0), 1685 + SND_SOC_DAPM_OUTPUT("OUT"), 1686 + SND_SOC_DAPM_INPUT("MIC"), 1687 + }; 1688 + 1689 + static const struct snd_soc_dapm_route pcmdevice_audio_map[] = { 1690 + {"OUT", NULL, "ASI"}, 1691 + {"ASI1 OUT", NULL, "MIC"}, 1692 + }; 1693 + 1694 + static const struct snd_soc_component_driver 1695 + soc_codec_driver_pcmdevice = { 1696 + .probe = pcmdevice_comp_probe, 1697 + .remove = pcmdevice_comp_remove, 1698 + .dapm_widgets = pcmdevice_dapm_widgets, 1699 + .num_dapm_widgets = ARRAY_SIZE(pcmdevice_dapm_widgets), 1700 + .dapm_routes = pcmdevice_audio_map, 1701 + .num_dapm_routes = ARRAY_SIZE(pcmdevice_audio_map), 1702 + .suspend_bias_off = 1, 1703 + .idle_bias_on = 0, 1704 + .use_pmdown_time = 1, 1705 + .endianness = 1, 1706 + }; 1707 + 1708 + static int pcmdev_single_byte_wr(struct pcmdevice_priv *pcm_dev, 1709 + unsigned char *data, int devn, int sublocksize) 1710 + { 1711 + unsigned short len = get_unaligned_be16(&data[2]); 1712 + int offset = 2; 1713 + int i, ret; 1714 + 1715 + offset += 2; 1716 + if (offset + 4 * len > sublocksize) { 1717 + dev_err(pcm_dev->dev, "%s: dev-%d byt wr out of boundary\n", 1718 + __func__, devn); 1719 + return -EINVAL; 1720 + } 1721 + 1722 + for (i = 0; i < len; i++) { 1723 + ret = pcmdev_dev_write(pcm_dev, devn, 1724 + PCMDEVICE_REG(data[offset + 1], data[offset + 2]), 1725 + data[offset + 3]); 1726 + /* skip this error for next operation or next devices */ 1727 + if (ret < 0) 1728 + dev_err(pcm_dev->dev, "%s: dev-%d single write err\n", 1729 + __func__, devn); 1730 + 1731 + offset += 4; 1732 + } 1733 + 1734 + return offset; 1735 + } 1736 + 1737 + static int pcmdev_burst_wr(struct pcmdevice_priv *pcm_dev, 1738 + unsigned char *data, int devn, int sublocksize) 1739 + { 1740 + unsigned short len = get_unaligned_be16(&data[2]); 1741 + int offset = 2; 1742 + int ret; 1743 + 1744 + offset += 2; 1745 + if (offset + 4 + len > sublocksize) { 1746 + dev_err(pcm_dev->dev, "%s: dev-%d burst Out of boundary\n", 1747 + __func__, devn); 1748 + return -EINVAL; 1749 + } 1750 + if (len % 4) { 1751 + dev_err(pcm_dev->dev, "%s: dev-%d bst-len(%u) not div by 4\n", 1752 + __func__, devn, len); 1753 + return -EINVAL; 1754 + } 1755 + ret = pcmdev_dev_bulk_write(pcm_dev, devn, 1756 + PCMDEVICE_REG(data[offset + 1], data[offset + 2]), 1757 + &(data[offset + 4]), len); 1758 + /* skip this error for next devices */ 1759 + if (ret < 0) 1760 + dev_err(pcm_dev->dev, "%s: dev-%d bulk_write err = %d\n", 1761 + __func__, devn, ret); 1762 + 1763 + offset += (len + 4); 1764 + 1765 + return offset; 1766 + } 1767 + 1768 + static int pcmdev_delay(struct pcmdevice_priv *pcm_dev, 1769 + unsigned char *data, int devn, int sublocksize) 1770 + { 1771 + unsigned int delay_time = 0; 1772 + int offset = 2; 1773 + 1774 + if (offset + 2 > sublocksize) { 1775 + dev_err(pcm_dev->dev, "%s: dev-%d deley out of boundary\n", 1776 + __func__, devn); 1777 + return -EINVAL; 1778 + } 1779 + delay_time = get_unaligned_be16(&data[2]) * 1000; 1780 + usleep_range(delay_time, delay_time + 50); 1781 + offset += 2; 1782 + 1783 + return offset; 1784 + } 1785 + 1786 + static int pcmdev_bits_wr(struct pcmdevice_priv *pcm_dev, 1787 + unsigned char *data, int devn, int sublocksize) 1788 + { 1789 + int offset = 2; 1790 + int ret; 1791 + 1792 + if (offset + 6 > sublocksize) { 1793 + dev_err(pcm_dev->dev, "%s: dev-%d bit write out of memory\n", 1794 + __func__, devn); 1795 + return -EINVAL; 1796 + } 1797 + ret = pcmdev_dev_update_bits(pcm_dev, devn, 1798 + PCMDEVICE_REG(data[offset + 3], data[offset + 4]), 1799 + data[offset + 1], data[offset + 5]); 1800 + /* skip this error for next devices */ 1801 + if (ret < 0) 1802 + dev_err(pcm_dev->dev, "%s: dev-%d update_bits err = %d\n", 1803 + __func__, devn, ret); 1804 + 1805 + offset += 6; 1806 + 1807 + return offset; 1808 + } 1809 + 1810 + static int pcmdevice_process_block(void *ctxt, unsigned char *data, 1811 + unsigned char dev_idx, int sublocksize) 1812 + { 1813 + struct pcmdevice_priv *pcm_dev = (struct pcmdevice_priv *)ctxt; 1814 + int devn, dev_end, ret = 0; 1815 + unsigned char subblk_typ = data[1]; 1816 + 1817 + if (dev_idx) { 1818 + devn = dev_idx - 1; 1819 + dev_end = dev_idx; 1820 + } else { 1821 + devn = 0; 1822 + dev_end = pcm_dev->ndev; 1823 + } 1824 + 1825 + /* loop in case of several devices sharing the same sub-block */ 1826 + for (; devn < dev_end; devn++) { 1827 + switch (subblk_typ) { 1828 + case PCMDEVICE_CMD_SING_W: 1829 + ret = pcmdev_single_byte_wr(pcm_dev, data, devn, sublocksize); 1830 + break; 1831 + case PCMDEVICE_CMD_BURST: 1832 + ret = pcmdev_burst_wr(pcm_dev, data, devn, sublocksize); 1833 + break; 1834 + case PCMDEVICE_CMD_DELAY: 1835 + ret = pcmdev_delay(pcm_dev, data, devn, sublocksize); 1836 + break; 1837 + case PCMDEVICE_CMD_FIELD_W: 1838 + ret = pcmdev_bits_wr(pcm_dev, data, devn, sublocksize); 1839 + break; 1840 + default: 1841 + break; 1842 + } 1843 + /* 1844 + * In case of sub-block error, break the loop for the rest of 1845 + * devices. 1846 + */ 1847 + if (ret < 0) 1848 + break; 1849 + } 1850 + 1851 + return ret; 1852 + } 1853 + 1854 + static void pcmdevice_select_cfg_blk(void *ctxt, int conf_no, 1855 + unsigned char block_type) 1856 + { 1857 + struct pcmdevice_priv *pcm_dev = (struct pcmdevice_priv *)ctxt; 1858 + struct pcmdevice_regbin *regbin = &(pcm_dev->regbin); 1859 + struct pcmdevice_config_info **cfg_info = regbin->cfg_info; 1860 + struct pcmdevice_block_data **blk_data; 1861 + int j, k; 1862 + 1863 + if (conf_no >= regbin->ncfgs || conf_no < 0 || NULL == cfg_info) { 1864 + dev_err(pcm_dev->dev, "%s: conf_no should be less than %u\n", 1865 + __func__, regbin->ncfgs); 1866 + goto out; 1867 + } 1868 + blk_data = cfg_info[conf_no]->blk_data; 1869 + 1870 + for (j = 0; j < (int)cfg_info[conf_no]->real_nblocks; j++) { 1871 + unsigned int length = 0, ret; 1872 + 1873 + if (block_type > 5 || block_type < 2) { 1874 + dev_err(pcm_dev->dev, 1875 + "%s: block_type should be out of range\n", 1876 + __func__); 1877 + goto out; 1878 + } 1879 + if (block_type != blk_data[j]->block_type) 1880 + continue; 1881 + 1882 + for (k = 0; k < (int)blk_data[j]->n_subblks; k++) { 1883 + ret = pcmdevice_process_block(pcm_dev, 1884 + blk_data[j]->regdata + length, 1885 + blk_data[j]->dev_idx, 1886 + blk_data[j]->block_size - length); 1887 + length += ret; 1888 + if (blk_data[j]->block_size < length) { 1889 + dev_err(pcm_dev->dev, 1890 + "%s: %u %u out of boundary\n", 1891 + __func__, length, 1892 + blk_data[j]->block_size); 1893 + break; 1894 + } 1895 + } 1896 + if (length != blk_data[j]->block_size) 1897 + dev_err(pcm_dev->dev, "%s: %u %u size is not same\n", 1898 + __func__, length, blk_data[j]->block_size); 1899 + } 1900 + 1901 + out: 1902 + return; 1903 + } 1904 + 1905 + static int pcmdevice_mute(struct snd_soc_dai *dai, int mute, int stream) 1906 + { 1907 + struct snd_soc_component *codec = dai->component; 1908 + struct pcmdevice_priv *pcm_dev = snd_soc_component_get_drvdata(codec); 1909 + unsigned char block_type; 1910 + 1911 + if (pcm_dev->fw_state == PCMDEVICE_FW_LOAD_FAILED) { 1912 + dev_err(pcm_dev->dev, "%s: bin file not loaded\n", __func__); 1913 + return -EINVAL; 1914 + } 1915 + 1916 + if (mute) 1917 + block_type = PCMDEVICE_BIN_BLK_PRE_SHUTDOWN; 1918 + else 1919 + block_type = PCMDEVICE_BIN_BLK_PRE_POWER_UP; 1920 + 1921 + mutex_lock(&pcm_dev->codec_lock); 1922 + pcmdevice_select_cfg_blk(pcm_dev, pcm_dev->cur_conf, block_type); 1923 + mutex_unlock(&pcm_dev->codec_lock); 1924 + return 0; 1925 + } 1926 + 1927 + static int pcmdevice_hw_params(struct snd_pcm_substream *substream, 1928 + struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) 1929 + { 1930 + struct pcmdevice_priv *pcm_dev = snd_soc_dai_get_drvdata(dai); 1931 + unsigned int fsrate; 1932 + unsigned int slot_width; 1933 + int bclk_rate; 1934 + int ret = 0; 1935 + 1936 + fsrate = params_rate(params); 1937 + switch (fsrate) { 1938 + case 48000: 1939 + break; 1940 + case 44100: 1941 + break; 1942 + default: 1943 + dev_err(pcm_dev->dev, "%s: incorrect sample rate = %u\n", 1944 + __func__, fsrate); 1945 + ret = -EINVAL; 1946 + goto out; 1947 + } 1948 + 1949 + slot_width = params_width(params); 1950 + switch (slot_width) { 1951 + case 16: 1952 + break; 1953 + case 20: 1954 + break; 1955 + case 24: 1956 + break; 1957 + case 32: 1958 + break; 1959 + default: 1960 + dev_err(pcm_dev->dev, "%s: incorrect slot width = %u\n", 1961 + __func__, slot_width); 1962 + ret = -EINVAL; 1963 + goto out; 1964 + } 1965 + 1966 + bclk_rate = snd_soc_params_to_bclk(params); 1967 + if (bclk_rate < 0) { 1968 + dev_err(pcm_dev->dev, "%s: incorrect bclk rate = %d\n", 1969 + __func__, bclk_rate); 1970 + ret = bclk_rate; 1971 + } 1972 + 1973 + out: 1974 + return ret; 1975 + } 1976 + 1977 + static const struct snd_soc_dai_ops pcmdevice_dai_ops = { 1978 + .mute_stream = pcmdevice_mute, 1979 + .hw_params = pcmdevice_hw_params, 1980 + }; 1981 + 1982 + static struct snd_soc_dai_driver pcmdevice_dai_driver[] = { 1983 + { 1984 + .name = "pcmdevice-codec", 1985 + .capture = { 1986 + .stream_name = "Capture", 1987 + .channels_min = 2, 1988 + .channels_max = PCMDEVICE_MAX_CHANNELS, 1989 + .rates = PCMDEVICE_RATES, 1990 + .formats = PCMDEVICE_FORMATS, 1991 + }, 1992 + .playback = { 1993 + .stream_name = "Playback", 1994 + .channels_min = 2, 1995 + .channels_max = PCMDEVICE_MAX_CHANNELS, 1996 + .rates = PCMDEVICE_RATES, 1997 + .formats = PCMDEVICE_FORMATS, 1998 + }, 1999 + .ops = &pcmdevice_dai_ops, 2000 + .symmetric_rate = 1, 2001 + } 2002 + }; 2003 + 2004 + #ifdef CONFIG_OF 2005 + static const struct of_device_id pcmdevice_of_match[] = { 2006 + { .compatible = "ti,adc3120" }, 2007 + { .compatible = "ti,adc5120" }, 2008 + { .compatible = "ti,adc6120" }, 2009 + { .compatible = "ti,dix4192" }, 2010 + { .compatible = "ti,pcm1690" }, 2011 + { .compatible = "ti,pcm3120" }, 2012 + { .compatible = "ti,pcm3140" }, 2013 + { .compatible = "ti,pcm5120" }, 2014 + { .compatible = "ti,pcm5140" }, 2015 + { .compatible = "ti,pcm6120" }, 2016 + { .compatible = "ti,pcm6140" }, 2017 + { .compatible = "ti,pcm6240" }, 2018 + { .compatible = "ti,pcm6260" }, 2019 + { .compatible = "ti,pcm9211" }, 2020 + { .compatible = "ti,pcmd3140" }, 2021 + { .compatible = "ti,pcmd3180" }, 2022 + { .compatible = "ti,pcmd512x" }, 2023 + { .compatible = "ti,taa5212" }, 2024 + { .compatible = "ti,taa5412" }, 2025 + { .compatible = "ti,tad5212" }, 2026 + { .compatible = "ti,tad5412" }, 2027 + {}, 2028 + }; 2029 + MODULE_DEVICE_TABLE(of, pcmdevice_of_match); 2030 + #endif 2031 + 2032 + static const struct regmap_range_cfg pcmdevice_ranges[] = { 2033 + { 2034 + .range_min = 0, 2035 + .range_max = 256 * 128, 2036 + .selector_reg = PCMDEVICE_PAGE_SELECT, 2037 + .selector_mask = 0xff, 2038 + .selector_shift = 0, 2039 + .window_start = 0, 2040 + .window_len = 128, 2041 + }, 2042 + }; 2043 + 2044 + static const struct regmap_config pcmdevice_i2c_regmap = { 2045 + .reg_bits = 8, 2046 + .val_bits = 8, 2047 + .cache_type = REGCACHE_MAPLE, 2048 + .ranges = pcmdevice_ranges, 2049 + .num_ranges = ARRAY_SIZE(pcmdevice_ranges), 2050 + .max_register = 256 * 128, 2051 + }; 2052 + 2053 + static void pcmdevice_remove(struct pcmdevice_priv *pcm_dev) 2054 + { 2055 + if (gpio_is_valid(pcm_dev->irq_info.gpio)) { 2056 + gpio_free(pcm_dev->irq_info.gpio); 2057 + free_irq(pcm_dev->irq_info.nmb, pcm_dev); 2058 + } 2059 + mutex_destroy(&pcm_dev->codec_lock); 2060 + } 2061 + 2062 + static char *str_to_upper(char *str) 2063 + { 2064 + char *orig = str; 2065 + 2066 + if (!str) 2067 + return NULL; 2068 + 2069 + while (*str) { 2070 + *str = toupper(*str); 2071 + str++; 2072 + } 2073 + 2074 + return orig; 2075 + } 2076 + 2077 + static int pcmdevice_i2c_probe(struct i2c_client *i2c) 2078 + { 2079 + const struct i2c_device_id *id = i2c_match_id(pcmdevice_i2c_id, i2c); 2080 + struct pcmdevice_priv *pcm_dev; 2081 + struct device_node *np; 2082 + unsigned int dev_addrs[PCMDEVICE_MAX_I2C_DEVICES]; 2083 + int ret = 0, i = 0, ndev = 0; 2084 + #ifdef CONFIG_OF 2085 + const __be32 *reg, *reg_end; 2086 + int len, sw, aw; 2087 + #endif 2088 + 2089 + pcm_dev = devm_kzalloc(&i2c->dev, sizeof(*pcm_dev), GFP_KERNEL); 2090 + if (!pcm_dev) { 2091 + ret = -ENOMEM; 2092 + goto out; 2093 + } 2094 + 2095 + pcm_dev->chip_id = (id != NULL) ? id->driver_data : 0; 2096 + 2097 + pcm_dev->dev = &i2c->dev; 2098 + pcm_dev->client = i2c; 2099 + 2100 + if (pcm_dev->chip_id >= MAX_DEVICE) 2101 + pcm_dev->chip_id = 0; 2102 + 2103 + strscpy(pcm_dev->dev_name, pcmdevice_i2c_id[pcm_dev->chip_id].name, 2104 + sizeof(pcm_dev->dev_name)); 2105 + 2106 + strscpy(pcm_dev->upper_dev_name, 2107 + pcmdevice_i2c_id[pcm_dev->chip_id].name, 2108 + sizeof(pcm_dev->upper_dev_name)); 2109 + 2110 + str_to_upper(pcm_dev->upper_dev_name); 2111 + 2112 + pcm_dev->regmap = devm_regmap_init_i2c(i2c, &pcmdevice_i2c_regmap); 2113 + if (IS_ERR(pcm_dev->regmap)) { 2114 + ret = PTR_ERR(pcm_dev->regmap); 2115 + dev_err(&i2c->dev, "%s: failed to allocate register map: %d\n", 2116 + __func__, ret); 2117 + goto out; 2118 + } 2119 + 2120 + i2c_set_clientdata(i2c, pcm_dev); 2121 + mutex_init(&pcm_dev->codec_lock); 2122 + np = pcm_dev->dev->of_node; 2123 + #ifdef CONFIG_OF 2124 + aw = of_n_addr_cells(np); 2125 + sw = of_n_size_cells(np); 2126 + if (sw == 0) { 2127 + reg = (const __be32 *)of_get_property(np, 2128 + "reg", &len); 2129 + reg_end = reg + len/sizeof(*reg); 2130 + ndev = 0; 2131 + do { 2132 + dev_addrs[ndev] = of_read_number(reg, aw); 2133 + reg += aw; 2134 + ndev++; 2135 + } while (reg < reg_end); 2136 + } else { 2137 + ndev = 1; 2138 + dev_addrs[0] = i2c->addr; 2139 + } 2140 + #else 2141 + ndev = 1; 2142 + dev_addrs[0] = i2c->addr; 2143 + #endif 2144 + pcm_dev->irq_info.gpio = of_irq_get(np, 0); 2145 + 2146 + for (i = 0; i < ndev; i++) 2147 + pcm_dev->addr[i] = dev_addrs[i]; 2148 + 2149 + pcm_dev->ndev = ndev; 2150 + 2151 + pcm_dev->hw_rst = devm_gpiod_get_optional(&i2c->dev, 2152 + "reset-gpios", GPIOD_OUT_HIGH); 2153 + /* No reset GPIO, no side-effect */ 2154 + if (IS_ERR(pcm_dev->hw_rst)) { 2155 + if (pcm_dev->chip_id == PCM9211 || pcm_dev->chip_id == PCM1690) 2156 + pcm9211_sw_rst(pcm_dev); 2157 + else 2158 + pcmdevice_sw_rst(pcm_dev); 2159 + } else { 2160 + gpiod_set_value_cansleep(pcm_dev->hw_rst, 0); 2161 + usleep_range(500, 1000); 2162 + gpiod_set_value_cansleep(pcm_dev->hw_rst, 1); 2163 + } 2164 + 2165 + if (pcm_dev->chip_id == PCM1690) 2166 + goto skip_interrupt; 2167 + if (gpio_is_valid(pcm_dev->irq_info.gpio)) { 2168 + dev_dbg(pcm_dev->dev, "irq-gpio = %d", pcm_dev->irq_info.gpio); 2169 + 2170 + ret = gpio_request(pcm_dev->irq_info.gpio, "PCMDEV-IRQ"); 2171 + if (!ret) { 2172 + int gpio = pcm_dev->irq_info.gpio; 2173 + 2174 + gpio_direction_input(gpio); 2175 + pcm_dev->irq_info.nmb = gpio_to_irq(gpio); 2176 + 2177 + } else 2178 + dev_err(pcm_dev->dev, "%s: GPIO %d request error\n", 2179 + __func__, pcm_dev->irq_info.gpio); 2180 + } else 2181 + dev_err(pcm_dev->dev, "Looking up irq-gpio failed %d\n", 2182 + pcm_dev->irq_info.gpio); 2183 + 2184 + skip_interrupt: 2185 + ret = devm_snd_soc_register_component(&i2c->dev, 2186 + &soc_codec_driver_pcmdevice, pcmdevice_dai_driver, 2187 + ARRAY_SIZE(pcmdevice_dai_driver)); 2188 + if (ret < 0) 2189 + dev_err(&i2c->dev, "probe register comp failed %d\n", ret); 2190 + 2191 + out: 2192 + if (ret < 0) 2193 + pcmdevice_remove(pcm_dev); 2194 + return ret; 2195 + } 2196 + 2197 + static void pcmdevice_i2c_remove(struct i2c_client *i2c) 2198 + { 2199 + struct pcmdevice_priv *pcm_dev = i2c_get_clientdata(i2c); 2200 + 2201 + pcmdevice_remove(pcm_dev); 2202 + } 2203 + 2204 + static struct i2c_driver pcmdevice_i2c_driver = { 2205 + .driver = { 2206 + .name = "pcmdevice-codec", 2207 + .of_match_table = of_match_ptr(pcmdevice_of_match), 2208 + }, 2209 + .probe = pcmdevice_i2c_probe, 2210 + .remove = pcmdevice_i2c_remove, 2211 + .id_table = pcmdevice_i2c_id, 2212 + }; 2213 + module_i2c_driver(pcmdevice_i2c_driver); 2214 + 2215 + MODULE_AUTHOR("Shenghao Ding <shenghao-ding@ti.com>"); 2216 + MODULE_DESCRIPTION("ASoC PCM6240 Family Audio ADC/DAC Driver"); 2217 + MODULE_LICENSE("GPL");
+252
sound/soc/codecs/pcm6240.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + // 3 + // ALSA SoC Texas Instruments PCM6240 Family Audio ADC/DAC/Router 4 + // 5 + // Copyright (C) 2022 - 2024 Texas Instruments Incorporated 6 + // https://www.ti.com 7 + // 8 + // The PCM6240 driver implements a flexible and configurable 9 + // algo coefficient setting for one, two, or even multiple 10 + // PCM6240 Family Audio chips. 11 + // 12 + // Author: Shenghao Ding <shenghao-ding@ti.com> 13 + // 14 + 15 + #ifndef __PCM6240_H__ 16 + #define __PCM6240_H__ 17 + 18 + enum pcm_device { 19 + ADC3120, 20 + ADC5120, 21 + ADC6120, 22 + DIX4192, 23 + PCM1690, 24 + PCM3120, 25 + PCM3140, 26 + PCM5120, 27 + PCM5140, 28 + PCM6120, 29 + PCM6140, 30 + PCM6240, 31 + PCM6260, 32 + PCM9211, 33 + PCMD3140, 34 + PCMD3180, 35 + PCMD512X, 36 + TAA5212, 37 + TAA5412, 38 + TAD5212, 39 + TAD5412, 40 + MAX_DEVICE, 41 + }; 42 + 43 + #define PCMDEV_GENERIC_VOL_CTRL 0x0 44 + #define PCMDEV_PCM1690_VOL_CTRL 0x1 45 + #define PCMDEV_PCM1690_FINE_VOL_CTRL 0x2 46 + 47 + /* Maximum number of I2C addresses */ 48 + #define PCMDEVICE_MAX_I2C_DEVICES 4 49 + /* Maximum number defined in REGBIN protocol */ 50 + #define PCMDEVICE_MAX_REGBIN_DEVICES 8 51 + #define PCMDEVICE_CONFIG_SUM 64 52 + #define PCMDEVICE_BIN_FILENAME_LEN 64 53 + 54 + #define PCMDEVICE_RATES (SNDRV_PCM_RATE_44100 | \ 55 + SNDRV_PCM_RATE_48000) 56 + #define PCMDEVICE_MAX_CHANNELS 8 57 + #define PCMDEVICE_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ 58 + SNDRV_PCM_FMTBIT_S20_3LE | \ 59 + SNDRV_PCM_FMTBIT_S24_3LE | \ 60 + SNDRV_PCM_FMTBIT_S24_LE | \ 61 + SNDRV_PCM_FMTBIT_S32_LE) 62 + 63 + /* PAGE Control Register (available in page0 of each book) */ 64 + #define PCMDEVICE_PAGE_SELECT 0x00 65 + #define PCMDEVICE_REG(page, reg) ((page * 128) + reg) 66 + #define PCMDEVICE_REG_SWRESET PCMDEVICE_REG(0X0, 0x01) 67 + #define PCMDEVICE_REG_SWRESET_RESET BIT(0) 68 + 69 + #define ADC5120_REG_CH1_ANALOG_GAIN PCMDEVICE_REG(0X0, 0x3d) 70 + #define ADC5120_REG_CH1_DIGITAL_GAIN PCMDEVICE_REG(0X0, 0x3e) 71 + #define ADC5120_REG_CH2_ANALOG_GAIN PCMDEVICE_REG(0X0, 0x42) 72 + #define ADC5120_REG_CH2_DIGITAL_GAIN PCMDEVICE_REG(0X0, 0x43) 73 + 74 + #define PCM1690_REG_MODE_CTRL PCMDEVICE_REG(0X0, 0x46) 75 + #define PCM1690_REG_MODE_CTRL_DAMS_MSK BIT(7) 76 + #define PCM1690_REG_MODE_CTRL_DAMS_FINE_STEP 0x0 77 + #define PCM1690_REG_MODE_CTRL_DAMS_WIDE_RANGE 0x80 78 + 79 + #define PCM1690_REG_CH1_DIGITAL_GAIN PCMDEVICE_REG(0X0, 0x48) 80 + #define PCM1690_REG_CH2_DIGITAL_GAIN PCMDEVICE_REG(0X0, 0x49) 81 + #define PCM1690_REG_CH3_DIGITAL_GAIN PCMDEVICE_REG(0X0, 0x4a) 82 + #define PCM1690_REG_CH4_DIGITAL_GAIN PCMDEVICE_REG(0X0, 0x4b) 83 + #define PCM1690_REG_CH5_DIGITAL_GAIN PCMDEVICE_REG(0X0, 0x4c) 84 + #define PCM1690_REG_CH6_DIGITAL_GAIN PCMDEVICE_REG(0X0, 0x4d) 85 + #define PCM1690_REG_CH7_DIGITAL_GAIN PCMDEVICE_REG(0X0, 0x4e) 86 + #define PCM1690_REG_CH8_DIGITAL_GAIN PCMDEVICE_REG(0X0, 0x4f) 87 + 88 + #define PCM6240_REG_CH1_ANALOG_GAIN PCMDEVICE_REG(0X0, 0x3d) 89 + #define PCM6240_REG_CH1_DIGITAL_GAIN PCMDEVICE_REG(0X0, 0x3e) 90 + #define PCM6240_REG_CH2_ANALOG_GAIN PCMDEVICE_REG(0X0, 0x42) 91 + #define PCM6240_REG_CH2_DIGITAL_GAIN PCMDEVICE_REG(0X0, 0x43) 92 + #define PCM6240_REG_CH3_ANALOG_GAIN PCMDEVICE_REG(0X0, 0x47) 93 + #define PCM6240_REG_CH3_DIGITAL_GAIN PCMDEVICE_REG(0X0, 0x48) 94 + #define PCM6240_REG_CH4_ANALOG_GAIN PCMDEVICE_REG(0X0, 0x4c) 95 + #define PCM6240_REG_CH4_DIGITAL_GAIN PCMDEVICE_REG(0X0, 0x4d) 96 + 97 + #define PCM6260_REG_CH1_ANALOG_GAIN PCMDEVICE_REG(0X0, 0x3d) 98 + #define PCM6260_REG_CH1_DIGITAL_GAIN PCMDEVICE_REG(0X0, 0x3e) 99 + #define PCM6260_REG_CH2_ANALOG_GAIN PCMDEVICE_REG(0X0, 0x42) 100 + #define PCM6260_REG_CH2_DIGITAL_GAIN PCMDEVICE_REG(0X0, 0x43) 101 + #define PCM6260_REG_CH3_ANALOG_GAIN PCMDEVICE_REG(0X0, 0x47) 102 + #define PCM6260_REG_CH3_DIGITAL_GAIN PCMDEVICE_REG(0X0, 0x48) 103 + #define PCM6260_REG_CH4_ANALOG_GAIN PCMDEVICE_REG(0X0, 0x4c) 104 + #define PCM6260_REG_CH4_DIGITAL_GAIN PCMDEVICE_REG(0X0, 0x4d) 105 + #define PCM6260_REG_CH5_ANALOG_GAIN PCMDEVICE_REG(0X0, 0x51) 106 + #define PCM6260_REG_CH5_DIGITAL_GAIN PCMDEVICE_REG(0X0, 0x52) 107 + #define PCM6260_REG_CH6_ANALOG_GAIN PCMDEVICE_REG(0X0, 0x56) 108 + #define PCM6260_REG_CH6_DIGITAL_GAIN PCMDEVICE_REG(0X0, 0x57) 109 + 110 + #define PCM9211_REG_SW_CTRL PCMDEVICE_REG(0X0, 0x40) 111 + #define PCM9211_REG_SW_CTRL_MRST_MSK BIT(7) 112 + #define PCM9211_REG_SW_CTRL_MRST 0x0 113 + 114 + #define PCM9211_REG_CH1_DIGITAL_GAIN PCMDEVICE_REG(0X0, 0x46) 115 + #define PCM9211_REG_CH2_DIGITAL_GAIN PCMDEVICE_REG(0X0, 0x47) 116 + 117 + #define PCMD3140_REG_CH1_DIGITAL_GAIN PCMDEVICE_REG(0X0, 0x3E) 118 + #define PCMD3140_REG_CH2_DIGITAL_GAIN PCMDEVICE_REG(0X0, 0x43) 119 + #define PCMD3140_REG_CH3_DIGITAL_GAIN PCMDEVICE_REG(0X0, 0x48) 120 + #define PCMD3140_REG_CH4_DIGITAL_GAIN PCMDEVICE_REG(0X0, 0x4D) 121 + 122 + #define PCMD3140_REG_CH1_FINE_GAIN PCMDEVICE_REG(0X0, 0x3F) 123 + #define PCMD3140_REG_CH2_FINE_GAIN PCMDEVICE_REG(0X0, 0x44) 124 + #define PCMD3140_REG_CH3_FINE_GAIN PCMDEVICE_REG(0X0, 0x49) 125 + #define PCMD3140_REG_CH4_FINE_GAIN PCMDEVICE_REG(0X0, 0x4E) 126 + 127 + #define PCMD3180_REG_CH1_DIGITAL_GAIN PCMDEVICE_REG(0X0, 0x3E) 128 + #define PCMD3180_REG_CH2_DIGITAL_GAIN PCMDEVICE_REG(0X0, 0x43) 129 + #define PCMD3180_REG_CH3_DIGITAL_GAIN PCMDEVICE_REG(0X0, 0x48) 130 + #define PCMD3180_REG_CH4_DIGITAL_GAIN PCMDEVICE_REG(0X0, 0x4D) 131 + #define PCMD3180_REG_CH5_DIGITAL_GAIN PCMDEVICE_REG(0X0, 0x52) 132 + #define PCMD3180_REG_CH6_DIGITAL_GAIN PCMDEVICE_REG(0X0, 0x57) 133 + #define PCMD3180_REG_CH7_DIGITAL_GAIN PCMDEVICE_REG(0X0, 0x5C) 134 + #define PCMD3180_REG_CH8_DIGITAL_GAIN PCMDEVICE_REG(0X0, 0x61) 135 + 136 + #define PCMD3180_REG_CH1_FINE_GAIN PCMDEVICE_REG(0X0, 0x3F) 137 + #define PCMD3180_REG_CH2_FINE_GAIN PCMDEVICE_REG(0X0, 0x44) 138 + #define PCMD3180_REG_CH3_FINE_GAIN PCMDEVICE_REG(0X0, 0x49) 139 + #define PCMD3180_REG_CH4_FINE_GAIN PCMDEVICE_REG(0X0, 0x4E) 140 + #define PCMD3180_REG_CH5_FINE_GAIN PCMDEVICE_REG(0X0, 0x53) 141 + #define PCMD3180_REG_CH6_FINE_GAIN PCMDEVICE_REG(0X0, 0x58) 142 + #define PCMD3180_REG_CH7_FINE_GAIN PCMDEVICE_REG(0X0, 0x5D) 143 + #define PCMD3180_REG_CH8_FINE_GAIN PCMDEVICE_REG(0X0, 0x62) 144 + 145 + #define TAA5412_REG_CH1_DIGITAL_VOLUME PCMDEVICE_REG(0X0, 0x52) 146 + #define TAA5412_REG_CH2_DIGITAL_VOLUME PCMDEVICE_REG(0X0, 0x57) 147 + #define TAA5412_REG_CH3_DIGITAL_VOLUME PCMDEVICE_REG(0X0, 0x5B) 148 + #define TAA5412_REG_CH4_DIGITAL_VOLUME PCMDEVICE_REG(0X0, 0x5F) 149 + 150 + #define TAA5412_REG_CH1_FINE_GAIN PCMDEVICE_REG(0X0, 0x53) 151 + #define TAA5412_REG_CH2_FINE_GAIN PCMDEVICE_REG(0X0, 0x58) 152 + #define TAA5412_REG_CH3_FINE_GAIN PCMDEVICE_REG(0X0, 0x5C) 153 + #define TAA5412_REG_CH4_FINE_GAIN PCMDEVICE_REG(0X0, 0x60) 154 + 155 + #define PCMDEVICE_CMD_SING_W 0x1 156 + #define PCMDEVICE_CMD_BURST 0x2 157 + #define PCMDEVICE_CMD_DELAY 0x3 158 + #define PCMDEVICE_CMD_FIELD_W 0x4 159 + 160 + enum pcmdevice_bin_blk_type { 161 + PCMDEVICE_BIN_BLK_COEFF = 1, 162 + PCMDEVICE_BIN_BLK_POST_POWER_UP, 163 + PCMDEVICE_BIN_BLK_PRE_SHUTDOWN, 164 + PCMDEVICE_BIN_BLK_PRE_POWER_UP, 165 + PCMDEVICE_BIN_BLK_POST_SHUTDOWN 166 + }; 167 + 168 + enum pcmdevice_fw_state { 169 + PCMDEVICE_FW_LOAD_OK = 0, 170 + PCMDEVICE_FW_LOAD_FAILED 171 + }; 172 + 173 + struct pcmdevice_regbin_hdr { 174 + unsigned int img_sz; 175 + unsigned int checksum; 176 + unsigned int binary_version_num; 177 + unsigned int drv_fw_version; 178 + unsigned int timestamp; 179 + unsigned char plat_type; 180 + unsigned char dev_family; 181 + unsigned char reserve; 182 + unsigned char ndev; 183 + unsigned char devs[PCMDEVICE_MAX_REGBIN_DEVICES]; 184 + unsigned int nconfig; 185 + unsigned int config_size[PCMDEVICE_CONFIG_SUM]; 186 + }; 187 + 188 + struct pcmdevice_block_data { 189 + unsigned char dev_idx; 190 + unsigned char block_type; 191 + unsigned short yram_checksum; 192 + unsigned int block_size; 193 + unsigned int n_subblks; 194 + unsigned char *regdata; 195 + }; 196 + 197 + struct pcmdevice_config_info { 198 + char cfg_name[64]; 199 + unsigned int nblocks; 200 + unsigned int real_nblocks; 201 + unsigned char active_dev; 202 + struct pcmdevice_block_data **blk_data; 203 + }; 204 + 205 + struct pcmdevice_regbin { 206 + struct pcmdevice_regbin_hdr fw_hdr; 207 + int ncfgs; 208 + struct pcmdevice_config_info **cfg_info; 209 + }; 210 + 211 + struct pcmdevice_irqinfo { 212 + int gpio; 213 + int nmb; 214 + }; 215 + 216 + struct pcmdevice_priv { 217 + struct snd_soc_component *component; 218 + struct i2c_client *client; 219 + struct device *dev; 220 + struct mutex codec_lock; 221 + struct gpio_desc *hw_rst; 222 + struct regmap *regmap; 223 + struct pcmdevice_regbin regbin; 224 + struct pcmdevice_irqinfo irq_info; 225 + unsigned int addr[PCMDEVICE_MAX_I2C_DEVICES]; 226 + unsigned int chip_id; 227 + int cur_conf; 228 + int fw_state; 229 + int ndev; 230 + unsigned char bin_name[PCMDEVICE_BIN_FILENAME_LEN]; 231 + /* used for kcontrol name */ 232 + unsigned char upper_dev_name[I2C_NAME_SIZE]; 233 + unsigned char dev_name[I2C_NAME_SIZE]; 234 + }; 235 + 236 + /* mixer control */ 237 + struct pcmdevice_mixer_control { 238 + int max; 239 + int reg; 240 + unsigned int dev_no; 241 + unsigned int shift; 242 + unsigned int invert; 243 + }; 244 + struct pcmdev_ctrl_info { 245 + const unsigned int *gain; 246 + const struct pcmdevice_mixer_control *pcmdev_ctrl; 247 + unsigned int ctrl_array_size; 248 + snd_kcontrol_get_t *get; 249 + snd_kcontrol_put_t *put; 250 + int pcmdev_ctrl_name_id; 251 + }; 252 + #endif /* __PCM6240_H__ */