aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs')
-rw-r--r--sound/soc/codecs/ab8500-codec.c79
-rw-r--r--sound/soc/codecs/ab8500-codec.h42
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
2383static 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
2365static struct snd_soc_dai_driver ab8500_codec_dai[] = { 2388static 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 */