diff options
Diffstat (limited to 'sound/soc/codecs')
-rw-r--r-- | sound/soc/codecs/ab8500-codec.c | 79 | ||||
-rw-r--r-- | sound/soc/codecs/ab8500-codec.h | 42 |
2 files changed, 68 insertions, 53 deletions
diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c index 3126cac7b7c8..b8ba0adacfce 100644 --- a/sound/soc/codecs/ab8500-codec.c +++ b/sound/soc/codecs/ab8500-codec.c | |||
@@ -2236,7 +2236,7 @@ static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai, | |||
2236 | int slots, int slot_width) | 2236 | int slots, int slot_width) |
2237 | { | 2237 | { |
2238 | struct snd_soc_codec *codec = dai->codec; | 2238 | struct snd_soc_codec *codec = dai->codec; |
2239 | unsigned int val, mask, slots_active; | 2239 | unsigned int val, mask, slot, slots_active; |
2240 | 2240 | ||
2241 | mask = BIT(AB8500_DIGIFCONF2_IF0WL0) | | 2241 | mask = BIT(AB8500_DIGIFCONF2_IF0WL0) | |
2242 | BIT(AB8500_DIGIFCONF2_IF0WL1); | 2242 | BIT(AB8500_DIGIFCONF2_IF0WL1); |
@@ -2292,27 +2292,34 @@ static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai, | |||
2292 | snd_soc_update_bits(codec, AB8500_DIGIFCONF1, mask, val); | 2292 | snd_soc_update_bits(codec, AB8500_DIGIFCONF1, mask, val); |
2293 | 2293 | ||
2294 | /* Setup TDM DA according to active tx slots */ | 2294 | /* Setup TDM DA according to active tx slots */ |
2295 | |||
2296 | if (tx_mask & ~0xff) | ||
2297 | return -EINVAL; | ||
2298 | |||
2295 | mask = AB8500_DASLOTCONFX_SLTODAX_MASK; | 2299 | mask = AB8500_DASLOTCONFX_SLTODAX_MASK; |
2300 | tx_mask = tx_mask << AB8500_DA_DATA0_OFFSET; | ||
2296 | slots_active = hweight32(tx_mask); | 2301 | slots_active = hweight32(tx_mask); |
2302 | |||
2297 | dev_dbg(dai->codec->dev, "%s: Slots, active, TX: %d\n", __func__, | 2303 | dev_dbg(dai->codec->dev, "%s: Slots, active, TX: %d\n", __func__, |
2298 | slots_active); | 2304 | slots_active); |
2305 | |||
2299 | switch (slots_active) { | 2306 | switch (slots_active) { |
2300 | case 0: | 2307 | case 0: |
2301 | break; | 2308 | break; |
2302 | case 1: | 2309 | case 1: |
2303 | /* Slot 9 -> DA_IN1 & DA_IN3 */ | 2310 | slot = find_first_bit((unsigned long *)&tx_mask, 32); |
2304 | snd_soc_update_bits(codec, AB8500_DASLOTCONF1, mask, 11); | 2311 | snd_soc_update_bits(codec, AB8500_DASLOTCONF1, mask, slot); |
2305 | snd_soc_update_bits(codec, AB8500_DASLOTCONF3, mask, 11); | 2312 | snd_soc_update_bits(codec, AB8500_DASLOTCONF3, mask, slot); |
2306 | snd_soc_update_bits(codec, AB8500_DASLOTCONF2, mask, 11); | 2313 | snd_soc_update_bits(codec, AB8500_DASLOTCONF2, mask, slot); |
2307 | snd_soc_update_bits(codec, AB8500_DASLOTCONF4, mask, 11); | 2314 | snd_soc_update_bits(codec, AB8500_DASLOTCONF4, mask, slot); |
2308 | break; | 2315 | break; |
2309 | case 2: | 2316 | case 2: |
2310 | /* Slot 9 -> DA_IN1 & DA_IN3, Slot 11 -> DA_IN2 & DA_IN4 */ | 2317 | slot = find_first_bit((unsigned long *)&tx_mask, 32); |
2311 | snd_soc_update_bits(codec, AB8500_DASLOTCONF1, mask, 9); | 2318 | snd_soc_update_bits(codec, AB8500_DASLOTCONF1, mask, slot); |
2312 | snd_soc_update_bits(codec, AB8500_DASLOTCONF3, mask, 9); | 2319 | snd_soc_update_bits(codec, AB8500_DASLOTCONF3, mask, slot); |
2313 | snd_soc_update_bits(codec, AB8500_DASLOTCONF2, mask, 11); | 2320 | slot = find_next_bit((unsigned long *)&tx_mask, 32, slot + 1); |
2314 | snd_soc_update_bits(codec, AB8500_DASLOTCONF4, mask, 11); | 2321 | snd_soc_update_bits(codec, AB8500_DASLOTCONF2, mask, slot); |
2315 | 2322 | snd_soc_update_bits(codec, AB8500_DASLOTCONF4, mask, slot); | |
2316 | break; | 2323 | break; |
2317 | case 8: | 2324 | case 8: |
2318 | dev_dbg(dai->codec->dev, | 2325 | dev_dbg(dai->codec->dev, |
@@ -2327,25 +2334,36 @@ static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai, | |||
2327 | } | 2334 | } |
2328 | 2335 | ||
2329 | /* Setup TDM AD according to active RX-slots */ | 2336 | /* Setup TDM AD according to active RX-slots */ |
2337 | |||
2338 | if (rx_mask & ~0xff) | ||
2339 | return -EINVAL; | ||
2340 | |||
2341 | rx_mask = rx_mask << AB8500_AD_DATA0_OFFSET; | ||
2330 | slots_active = hweight32(rx_mask); | 2342 | slots_active = hweight32(rx_mask); |
2343 | |||
2331 | dev_dbg(dai->codec->dev, "%s: Slots, active, RX: %d\n", __func__, | 2344 | dev_dbg(dai->codec->dev, "%s: Slots, active, RX: %d\n", __func__, |
2332 | slots_active); | 2345 | slots_active); |
2346 | |||
2333 | switch (slots_active) { | 2347 | switch (slots_active) { |
2334 | case 0: | 2348 | case 0: |
2335 | break; | 2349 | break; |
2336 | case 1: | 2350 | case 1: |
2337 | /* AD_OUT3 -> slot 0 & 1 */ | 2351 | slot = find_first_bit((unsigned long *)&rx_mask, 32); |
2338 | snd_soc_update_bits(codec, AB8500_ADSLOTSEL1, AB8500_MASK_ALL, | 2352 | snd_soc_update_bits(codec, AB8500_ADSLOTSEL(slot), |
2339 | AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_EVEN | | 2353 | AB8500_MASK_SLOT(slot), |
2340 | AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_ODD); | 2354 | AB8500_ADSLOTSELX_AD_OUT_TO_SLOT(AB8500_AD_OUT3, slot)); |
2341 | break; | 2355 | break; |
2342 | case 2: | 2356 | case 2: |
2343 | /* AD_OUT3 -> slot 0, AD_OUT2 -> slot 1 */ | 2357 | slot = find_first_bit((unsigned long *)&rx_mask, 32); |
2358 | snd_soc_update_bits(codec, | ||
2359 | AB8500_ADSLOTSEL(slot), | ||
2360 | AB8500_MASK_SLOT(slot), | ||
2361 | AB8500_ADSLOTSELX_AD_OUT_TO_SLOT(AB8500_AD_OUT3, slot)); | ||
2362 | slot = find_next_bit((unsigned long *)&rx_mask, 32, slot + 1); | ||
2344 | snd_soc_update_bits(codec, | 2363 | snd_soc_update_bits(codec, |
2345 | AB8500_ADSLOTSEL1, | 2364 | AB8500_ADSLOTSEL(slot), |
2346 | AB8500_MASK_ALL, | 2365 | AB8500_MASK_SLOT(slot), |
2347 | AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_EVEN | | 2366 | AB8500_ADSLOTSELX_AD_OUT_TO_SLOT(AB8500_AD_OUT2, slot)); |
2348 | AB8500_ADSLOTSELX_AD_OUT2_TO_SLOT_ODD); | ||
2349 | break; | 2367 | break; |
2350 | case 8: | 2368 | case 8: |
2351 | dev_dbg(dai->codec->dev, | 2369 | dev_dbg(dai->codec->dev, |
@@ -2362,6 +2380,11 @@ static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai, | |||
2362 | return 0; | 2380 | return 0; |
2363 | } | 2381 | } |
2364 | 2382 | ||
2383 | static const struct snd_soc_dai_ops ab8500_codec_ops = { | ||
2384 | .set_fmt = ab8500_codec_set_dai_fmt, | ||
2385 | .set_tdm_slot = ab8500_codec_set_dai_tdm_slot, | ||
2386 | }; | ||
2387 | |||
2365 | static struct snd_soc_dai_driver ab8500_codec_dai[] = { | 2388 | static struct snd_soc_dai_driver ab8500_codec_dai[] = { |
2366 | { | 2389 | { |
2367 | .name = "ab8500-codec-dai.0", | 2390 | .name = "ab8500-codec-dai.0", |
@@ -2373,12 +2396,7 @@ static struct snd_soc_dai_driver ab8500_codec_dai[] = { | |||
2373 | .rates = AB8500_SUPPORTED_RATE, | 2396 | .rates = AB8500_SUPPORTED_RATE, |
2374 | .formats = AB8500_SUPPORTED_FMT, | 2397 | .formats = AB8500_SUPPORTED_FMT, |
2375 | }, | 2398 | }, |
2376 | .ops = (struct snd_soc_dai_ops[]) { | 2399 | .ops = &ab8500_codec_ops, |
2377 | { | ||
2378 | .set_tdm_slot = ab8500_codec_set_dai_tdm_slot, | ||
2379 | .set_fmt = ab8500_codec_set_dai_fmt, | ||
2380 | } | ||
2381 | }, | ||
2382 | .symmetric_rates = 1 | 2400 | .symmetric_rates = 1 |
2383 | }, | 2401 | }, |
2384 | { | 2402 | { |
@@ -2391,12 +2409,7 @@ static struct snd_soc_dai_driver ab8500_codec_dai[] = { | |||
2391 | .rates = AB8500_SUPPORTED_RATE, | 2409 | .rates = AB8500_SUPPORTED_RATE, |
2392 | .formats = AB8500_SUPPORTED_FMT, | 2410 | .formats = AB8500_SUPPORTED_FMT, |
2393 | }, | 2411 | }, |
2394 | .ops = (struct snd_soc_dai_ops[]) { | 2412 | .ops = &ab8500_codec_ops, |
2395 | { | ||
2396 | .set_tdm_slot = ab8500_codec_set_dai_tdm_slot, | ||
2397 | .set_fmt = ab8500_codec_set_dai_fmt, | ||
2398 | } | ||
2399 | }, | ||
2400 | .symmetric_rates = 1 | 2413 | .symmetric_rates = 1 |
2401 | } | 2414 | } |
2402 | }; | 2415 | }; |
diff --git a/sound/soc/codecs/ab8500-codec.h b/sound/soc/codecs/ab8500-codec.h index 306d0bc8455f..e2e54425d25e 100644 --- a/sound/soc/codecs/ab8500-codec.h +++ b/sound/soc/codecs/ab8500-codec.h | |||
@@ -24,6 +24,13 @@ | |||
24 | #define AB8500_SUPPORTED_RATE (SNDRV_PCM_RATE_48000) | 24 | #define AB8500_SUPPORTED_RATE (SNDRV_PCM_RATE_48000) |
25 | #define AB8500_SUPPORTED_FMT (SNDRV_PCM_FMTBIT_S16_LE) | 25 | #define AB8500_SUPPORTED_FMT (SNDRV_PCM_FMTBIT_S16_LE) |
26 | 26 | ||
27 | /* AB8500 interface slot offset definitions */ | ||
28 | |||
29 | #define AB8500_AD_DATA0_OFFSET 0 | ||
30 | #define AB8500_DA_DATA0_OFFSET 8 | ||
31 | #define AB8500_AD_DATA1_OFFSET 16 | ||
32 | #define AB8500_DA_DATA1_OFFSET 24 | ||
33 | |||
27 | /* AB8500 audio bank (0x0d) register definitions */ | 34 | /* AB8500 audio bank (0x0d) register definitions */ |
28 | 35 | ||
29 | #define AB8500_POWERUP 0x00 | 36 | #define AB8500_POWERUP 0x00 |
@@ -73,6 +80,7 @@ | |||
73 | #define AB8500_ADSLOTSEL14 0x2C | 80 | #define AB8500_ADSLOTSEL14 0x2C |
74 | #define AB8500_ADSLOTSEL15 0x2D | 81 | #define AB8500_ADSLOTSEL15 0x2D |
75 | #define AB8500_ADSLOTSEL16 0x2E | 82 | #define AB8500_ADSLOTSEL16 0x2E |
83 | #define AB8500_ADSLOTSEL(slot) (AB8500_ADSLOTSEL1 + (slot >> 1)) | ||
76 | #define AB8500_ADSLOTHIZCTRL1 0x2F | 84 | #define AB8500_ADSLOTHIZCTRL1 0x2F |
77 | #define AB8500_ADSLOTHIZCTRL2 0x30 | 85 | #define AB8500_ADSLOTHIZCTRL2 0x30 |
78 | #define AB8500_ADSLOTHIZCTRL3 0x31 | 86 | #define AB8500_ADSLOTHIZCTRL3 0x31 |
@@ -144,6 +152,7 @@ | |||
144 | #define AB8500_CACHEREGNUM (AB8500_LAST_REG + 1) | 152 | #define AB8500_CACHEREGNUM (AB8500_LAST_REG + 1) |
145 | 153 | ||
146 | #define AB8500_MASK_ALL 0xFF | 154 | #define AB8500_MASK_ALL 0xFF |
155 | #define AB8500_MASK_SLOT(slot) ((slot & 1) ? 0xF0 : 0x0F) | ||
147 | #define AB8500_MASK_NONE 0x00 | 156 | #define AB8500_MASK_NONE 0x00 |
148 | 157 | ||
149 | /* AB8500_POWERUP */ | 158 | /* AB8500_POWERUP */ |
@@ -347,28 +356,21 @@ | |||
347 | #define AB8500_DIGIFCONF4_IF1WL0 0 | 356 | #define AB8500_DIGIFCONF4_IF1WL0 0 |
348 | 357 | ||
349 | /* AB8500_ADSLOTSELX */ | 358 | /* AB8500_ADSLOTSELX */ |
350 | #define AB8500_ADSLOTSELX_AD_OUT1_TO_SLOT_ODD 0x00 | 359 | #define AB8500_AD_OUT1 0x0 |
351 | #define AB8500_ADSLOTSELX_AD_OUT2_TO_SLOT_ODD 0x10 | 360 | #define AB8500_AD_OUT2 0x1 |
352 | #define AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_ODD 0x20 | 361 | #define AB8500_AD_OUT3 0x2 |
353 | #define AB8500_ADSLOTSELX_AD_OUT4_TO_SLOT_ODD 0x30 | 362 | #define AB8500_AD_OUT4 0x3 |
354 | #define AB8500_ADSLOTSELX_AD_OUT5_TO_SLOT_ODD 0x40 | 363 | #define AB8500_AD_OUT5 0x4 |
355 | #define AB8500_ADSLOTSELX_AD_OUT6_TO_SLOT_ODD 0x50 | 364 | #define AB8500_AD_OUT6 0x5 |
356 | #define AB8500_ADSLOTSELX_AD_OUT7_TO_SLOT_ODD 0x60 | 365 | #define AB8500_AD_OUT7 0x6 |
357 | #define AB8500_ADSLOTSELX_AD_OUT8_TO_SLOT_ODD 0x70 | 366 | #define AB8500_AD_OUT8 0x7 |
358 | #define AB8500_ADSLOTSELX_ZEROES_TO_SLOT_ODD 0x80 | 367 | #define AB8500_ZEROES 0x8 |
359 | #define AB8500_ADSLOTSELX_TRISTATE_TO_SLOT_ODD 0xF0 | 368 | #define AB8500_TRISTATE 0xF |
360 | #define AB8500_ADSLOTSELX_AD_OUT1_TO_SLOT_EVEN 0x00 | ||
361 | #define AB8500_ADSLOTSELX_AD_OUT2_TO_SLOT_EVEN 0x01 | ||
362 | #define AB8500_ADSLOTSELX_AD_OUT3_TO_SLOT_EVEN 0x02 | ||
363 | #define AB8500_ADSLOTSELX_AD_OUT4_TO_SLOT_EVEN 0x03 | ||
364 | #define AB8500_ADSLOTSELX_AD_OUT5_TO_SLOT_EVEN 0x04 | ||
365 | #define AB8500_ADSLOTSELX_AD_OUT6_TO_SLOT_EVEN 0x05 | ||
366 | #define AB8500_ADSLOTSELX_AD_OUT7_TO_SLOT_EVEN 0x06 | ||
367 | #define AB8500_ADSLOTSELX_AD_OUT8_TO_SLOT_EVEN 0x07 | ||
368 | #define AB8500_ADSLOTSELX_ZEROES_TO_SLOT_EVEN 0x08 | ||
369 | #define AB8500_ADSLOTSELX_TRISTATE_TO_SLOT_EVEN 0x0F | ||
370 | #define AB8500_ADSLOTSELX_EVEN_SHIFT 0 | 369 | #define AB8500_ADSLOTSELX_EVEN_SHIFT 0 |
371 | #define AB8500_ADSLOTSELX_ODD_SHIFT 4 | 370 | #define AB8500_ADSLOTSELX_ODD_SHIFT 4 |
371 | #define AB8500_ADSLOTSELX_AD_OUT_TO_SLOT(out, slot) \ | ||
372 | ((out) << (((slot) & 1) ? \ | ||
373 | AB8500_ADSLOTSELX_ODD_SHIFT : AB8500_ADSLOTSELX_EVEN_SHIFT)) | ||
372 | 374 | ||
373 | /* AB8500_ADSLOTHIZCTRL1 */ | 375 | /* AB8500_ADSLOTHIZCTRL1 */ |
374 | /* AB8500_ADSLOTHIZCTRL2 */ | 376 | /* AB8500_ADSLOTHIZCTRL2 */ |