| OLD | NEW |
| 1 /* | 1 /* |
| 2 * wm8904.c -- WM8904 ALSA SoC Audio driver | 2 * wm8904.c -- WM8904 ALSA SoC Audio driver |
| 3 * | 3 * |
| 4 * Copyright 2009 Wolfson Microelectronics plc | 4 * Copyright 2009 Wolfson Microelectronics plc |
| 5 * | 5 * |
| 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> | 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> |
| 7 * | 7 * |
| 8 * | 8 * |
| 9 * This program is free software; you can redistribute it and/or modify | 9 * This program is free software; you can redistribute it and/or modify |
| 10 * it under the terms of the GNU General Public License version 2 as | 10 * it under the terms of the GNU General Public License version 2 as |
| 11 * published by the Free Software Foundation. | 11 * published by the Free Software Foundation. |
| 12 */ | 12 */ |
| 13 | 13 |
| 14 #include <linux/module.h> | 14 #include <linux/module.h> |
| 15 #include <linux/moduleparam.h> | 15 #include <linux/moduleparam.h> |
| 16 #include <linux/init.h> | 16 #include <linux/init.h> |
| 17 #include <linux/delay.h> | 17 #include <linux/delay.h> |
| 18 #include <linux/pm.h> | 18 #include <linux/pm.h> |
| 19 #include <linux/i2c.h> | 19 #include <linux/i2c.h> |
| 20 #include <linux/platform_device.h> | 20 #include <linux/platform_device.h> |
| 21 #include <linux/regulator/consumer.h> | 21 #include <linux/regulator/consumer.h> |
| 22 #include <linux/slab.h> | 22 #include <linux/slab.h> |
| 23 #include <sound/core.h> | 23 #include <sound/core.h> |
| 24 #include <sound/pcm.h> | 24 #include <sound/pcm.h> |
| 25 #include <sound/pcm_params.h> | 25 #include <sound/pcm_params.h> |
| 26 #include <sound/soc.h> | 26 #include <sound/soc.h> |
| 27 #include <sound/soc-dapm.h> | |
| 28 #include <sound/initval.h> | 27 #include <sound/initval.h> |
| 29 #include <sound/tlv.h> | 28 #include <sound/tlv.h> |
| 30 #include <sound/wm8904.h> | 29 #include <sound/wm8904.h> |
| 31 | 30 |
| 32 #include "wm8904.h" | 31 #include "wm8904.h" |
| 33 | 32 |
| 34 enum wm8904_type { | 33 enum wm8904_type { |
| 35 WM8904, | 34 WM8904, |
| 36 WM8912, | 35 WM8912, |
| 37 }; | 36 }; |
| (...skipping 552 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 590 { 0x0000, 0x0000, 0 }, /* R241 */ | 589 { 0x0000, 0x0000, 0 }, /* R241 */ |
| 591 { 0x0000, 0x0000, 0 }, /* R242 */ | 590 { 0x0000, 0x0000, 0 }, /* R242 */ |
| 592 { 0x0000, 0x0000, 0 }, /* R243 */ | 591 { 0x0000, 0x0000, 0 }, /* R243 */ |
| 593 { 0x0000, 0x0000, 0 }, /* R244 */ | 592 { 0x0000, 0x0000, 0 }, /* R244 */ |
| 594 { 0x0000, 0x0000, 0 }, /* R245 */ | 593 { 0x0000, 0x0000, 0 }, /* R245 */ |
| 595 { 0x0000, 0x0000, 0 }, /* R246 */ | 594 { 0x0000, 0x0000, 0 }, /* R246 */ |
| 596 { 0x0001, 0x0001, 0 }, /* R247 - FLL NCO Test 0 */ | 595 { 0x0001, 0x0001, 0 }, /* R247 - FLL NCO Test 0 */ |
| 597 { 0x003F, 0x003F, 0 }, /* R248 - FLL NCO Test 1 */ | 596 { 0x003F, 0x003F, 0 }, /* R248 - FLL NCO Test 1 */ |
| 598 }; | 597 }; |
| 599 | 598 |
| 600 static int wm8904_volatile_register(unsigned int reg) | 599 static int wm8904_volatile_register(struct snd_soc_codec *codec, unsigned int re
g) |
| 601 { | 600 { |
| 602 return wm8904_access[reg].vol; | 601 return wm8904_access[reg].vol; |
| 603 } | 602 } |
| 604 | 603 |
| 605 static int wm8904_reset(struct snd_soc_codec *codec) | 604 static int wm8904_reset(struct snd_soc_codec *codec) |
| 606 { | 605 { |
| 607 return snd_soc_write(codec, WM8904_SW_RESET_AND_ID, 0); | 606 return snd_soc_write(codec, WM8904_SW_RESET_AND_ID, 0); |
| 608 } | 607 } |
| 609 | 608 |
| 610 static int wm8904_configure_clocking(struct snd_soc_codec *codec) | 609 static int wm8904_configure_clocking(struct snd_soc_codec *codec) |
| (...skipping 809 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1420 { "HPL PGA", NULL, "DACL" }, | 1419 { "HPL PGA", NULL, "DACL" }, |
| 1421 { "HPR PGA", NULL, "DACR" }, | 1420 { "HPR PGA", NULL, "DACR" }, |
| 1422 | 1421 |
| 1423 { "LINEL PGA", NULL, "DACL" }, | 1422 { "LINEL PGA", NULL, "DACL" }, |
| 1424 { "LINER PGA", NULL, "DACR" }, | 1423 { "LINER PGA", NULL, "DACR" }, |
| 1425 }; | 1424 }; |
| 1426 | 1425 |
| 1427 static int wm8904_add_widgets(struct snd_soc_codec *codec) | 1426 static int wm8904_add_widgets(struct snd_soc_codec *codec) |
| 1428 { | 1427 { |
| 1429 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); | 1428 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); |
| 1429 struct snd_soc_dapm_context *dapm = &codec->dapm; |
| 1430 | 1430 |
| 1431 » snd_soc_dapm_new_controls(codec, wm8904_core_dapm_widgets, | 1431 » snd_soc_dapm_new_controls(dapm, wm8904_core_dapm_widgets, |
| 1432 ARRAY_SIZE(wm8904_core_dapm_widgets)); | 1432 ARRAY_SIZE(wm8904_core_dapm_widgets)); |
| 1433 » snd_soc_dapm_add_routes(codec, core_intercon, | 1433 » snd_soc_dapm_add_routes(dapm, core_intercon, |
| 1434 ARRAY_SIZE(core_intercon)); | 1434 ARRAY_SIZE(core_intercon)); |
| 1435 | 1435 |
| 1436 switch (wm8904->devtype) { | 1436 switch (wm8904->devtype) { |
| 1437 case WM8904: | 1437 case WM8904: |
| 1438 snd_soc_add_controls(codec, wm8904_adc_snd_controls, | 1438 snd_soc_add_controls(codec, wm8904_adc_snd_controls, |
| 1439 ARRAY_SIZE(wm8904_adc_snd_controls)); | 1439 ARRAY_SIZE(wm8904_adc_snd_controls)); |
| 1440 snd_soc_add_controls(codec, wm8904_dac_snd_controls, | 1440 snd_soc_add_controls(codec, wm8904_dac_snd_controls, |
| 1441 ARRAY_SIZE(wm8904_dac_snd_controls)); | 1441 ARRAY_SIZE(wm8904_dac_snd_controls)); |
| 1442 snd_soc_add_controls(codec, wm8904_snd_controls, | 1442 snd_soc_add_controls(codec, wm8904_snd_controls, |
| 1443 ARRAY_SIZE(wm8904_snd_controls)); | 1443 ARRAY_SIZE(wm8904_snd_controls)); |
| 1444 | 1444 |
| 1445 » » snd_soc_dapm_new_controls(codec, wm8904_adc_dapm_widgets, | 1445 » » snd_soc_dapm_new_controls(dapm, wm8904_adc_dapm_widgets, |
| 1446 ARRAY_SIZE(wm8904_adc_dapm_widgets)); | 1446 ARRAY_SIZE(wm8904_adc_dapm_widgets)); |
| 1447 » » snd_soc_dapm_new_controls(codec, wm8904_dac_dapm_widgets, | 1447 » » snd_soc_dapm_new_controls(dapm, wm8904_dac_dapm_widgets, |
| 1448 ARRAY_SIZE(wm8904_dac_dapm_widgets)); | 1448 ARRAY_SIZE(wm8904_dac_dapm_widgets)); |
| 1449 » » snd_soc_dapm_new_controls(codec, wm8904_dapm_widgets, | 1449 » » snd_soc_dapm_new_controls(dapm, wm8904_dapm_widgets, |
| 1450 ARRAY_SIZE(wm8904_dapm_widgets)); | 1450 ARRAY_SIZE(wm8904_dapm_widgets)); |
| 1451 | 1451 |
| 1452 » » snd_soc_dapm_add_routes(codec, core_intercon, | 1452 » » snd_soc_dapm_add_routes(dapm, core_intercon, |
| 1453 ARRAY_SIZE(core_intercon)); | 1453 ARRAY_SIZE(core_intercon)); |
| 1454 » » snd_soc_dapm_add_routes(codec, adc_intercon, | 1454 » » snd_soc_dapm_add_routes(dapm, adc_intercon, |
| 1455 ARRAY_SIZE(adc_intercon)); | 1455 ARRAY_SIZE(adc_intercon)); |
| 1456 » » snd_soc_dapm_add_routes(codec, dac_intercon, | 1456 » » snd_soc_dapm_add_routes(dapm, dac_intercon, |
| 1457 ARRAY_SIZE(dac_intercon)); | 1457 ARRAY_SIZE(dac_intercon)); |
| 1458 » » snd_soc_dapm_add_routes(codec, wm8904_intercon, | 1458 » » snd_soc_dapm_add_routes(dapm, wm8904_intercon, |
| 1459 ARRAY_SIZE(wm8904_intercon)); | 1459 ARRAY_SIZE(wm8904_intercon)); |
| 1460 break; | 1460 break; |
| 1461 | 1461 |
| 1462 case WM8912: | 1462 case WM8912: |
| 1463 snd_soc_add_controls(codec, wm8904_dac_snd_controls, | 1463 snd_soc_add_controls(codec, wm8904_dac_snd_controls, |
| 1464 ARRAY_SIZE(wm8904_dac_snd_controls)); | 1464 ARRAY_SIZE(wm8904_dac_snd_controls)); |
| 1465 | 1465 |
| 1466 » » snd_soc_dapm_new_controls(codec, wm8904_dac_dapm_widgets, | 1466 » » snd_soc_dapm_new_controls(dapm, wm8904_dac_dapm_widgets, |
| 1467 ARRAY_SIZE(wm8904_dac_dapm_widgets)); | 1467 ARRAY_SIZE(wm8904_dac_dapm_widgets)); |
| 1468 | 1468 |
| 1469 » » snd_soc_dapm_add_routes(codec, dac_intercon, | 1469 » » snd_soc_dapm_add_routes(dapm, dac_intercon, |
| 1470 ARRAY_SIZE(dac_intercon)); | 1470 ARRAY_SIZE(dac_intercon)); |
| 1471 » » snd_soc_dapm_add_routes(codec, wm8912_intercon, | 1471 » » snd_soc_dapm_add_routes(dapm, wm8912_intercon, |
| 1472 ARRAY_SIZE(wm8912_intercon)); | 1472 ARRAY_SIZE(wm8912_intercon)); |
| 1473 break; | 1473 break; |
| 1474 } | 1474 } |
| 1475 | 1475 |
| 1476 » snd_soc_dapm_new_widgets(codec); | 1476 » snd_soc_dapm_new_widgets(dapm); |
| 1477 return 0; | 1477 return 0; |
| 1478 } | 1478 } |
| 1479 | 1479 |
| 1480 static struct { | 1480 static struct { |
| 1481 int ratio; | 1481 int ratio; |
| 1482 unsigned int clk_sys_rate; | 1482 unsigned int clk_sys_rate; |
| 1483 } clk_sys_rates[] = { | 1483 } clk_sys_rates[] = { |
| 1484 { 64, 0 }, | 1484 { 64, 0 }, |
| 1485 { 128, 1 }, | 1485 { 128, 1 }, |
| 1486 { 192, 2 }, | 1486 { 192, 2 }, |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1582 ret = wm8904_configure_clocking(codec); | 1582 ret = wm8904_configure_clocking(codec); |
| 1583 if (ret != 0) | 1583 if (ret != 0) |
| 1584 return ret; | 1584 return ret; |
| 1585 | 1585 |
| 1586 /* Select nearest CLK_SYS_RATE */ | 1586 /* Select nearest CLK_SYS_RATE */ |
| 1587 best = 0; | 1587 best = 0; |
| 1588 best_val = abs((wm8904->sysclk_rate / clk_sys_rates[0].ratio) | 1588 best_val = abs((wm8904->sysclk_rate / clk_sys_rates[0].ratio) |
| 1589 - wm8904->fs); | 1589 - wm8904->fs); |
| 1590 for (i = 1; i < ARRAY_SIZE(clk_sys_rates); i++) { | 1590 for (i = 1; i < ARRAY_SIZE(clk_sys_rates); i++) { |
| 1591 cur_val = abs((wm8904->sysclk_rate / | 1591 cur_val = abs((wm8904->sysclk_rate / |
| 1592 » » » clk_sys_rates[i].ratio) - wm8904->fs);; | 1592 » » » clk_sys_rates[i].ratio) - wm8904->fs); |
| 1593 if (cur_val < best_val) { | 1593 if (cur_val < best_val) { |
| 1594 best = i; | 1594 best = i; |
| 1595 best_val = cur_val; | 1595 best_val = cur_val; |
| 1596 } | 1596 } |
| 1597 } | 1597 } |
| 1598 dev_dbg(codec->dev, "Selected CLK_SYS_RATIO of %d\n", | 1598 dev_dbg(codec->dev, "Selected CLK_SYS_RATIO of %d\n", |
| 1599 clk_sys_rates[best].ratio); | 1599 clk_sys_rates[best].ratio); |
| 1600 clock1 |= (clk_sys_rates[best].clk_sys_rate | 1600 clock1 |= (clk_sys_rates[best].clk_sys_rate |
| 1601 << WM8904_CLK_SYS_RATE_SHIFT); | 1601 << WM8904_CLK_SYS_RATE_SHIFT); |
| 1602 | 1602 |
| (...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2131 snd_soc_update_bits(codec, WM8904_VMID_CONTROL_0, | 2131 snd_soc_update_bits(codec, WM8904_VMID_CONTROL_0, |
| 2132 WM8904_VMID_RES_MASK, | 2132 WM8904_VMID_RES_MASK, |
| 2133 0x1 << WM8904_VMID_RES_SHIFT); | 2133 0x1 << WM8904_VMID_RES_SHIFT); |
| 2134 | 2134 |
| 2135 /* Normal bias current */ | 2135 /* Normal bias current */ |
| 2136 snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0, | 2136 snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0, |
| 2137 WM8904_ISEL_MASK, 2 << WM8904_ISEL_SHIFT); | 2137 WM8904_ISEL_MASK, 2 << WM8904_ISEL_SHIFT); |
| 2138 break; | 2138 break; |
| 2139 | 2139 |
| 2140 case SND_SOC_BIAS_STANDBY: | 2140 case SND_SOC_BIAS_STANDBY: |
| 2141 » » if (codec->bias_level == SND_SOC_BIAS_OFF) { | 2141 » » if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { |
| 2142 ret = regulator_bulk_enable(ARRAY_SIZE(wm8904->supplies)
, | 2142 ret = regulator_bulk_enable(ARRAY_SIZE(wm8904->supplies)
, |
| 2143 wm8904->supplies); | 2143 wm8904->supplies); |
| 2144 if (ret != 0) { | 2144 if (ret != 0) { |
| 2145 dev_err(codec->dev, | 2145 dev_err(codec->dev, |
| 2146 "Failed to enable supplies: %d\n", | 2146 "Failed to enable supplies: %d\n", |
| 2147 ret); | 2147 ret); |
| 2148 return ret; | 2148 return ret; |
| 2149 } | 2149 } |
| 2150 | 2150 |
| 2151 wm8904_sync_cache(codec); | 2151 wm8904_sync_cache(codec); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2190 * for now just assume that the power will be cut if | 2190 * for now just assume that the power will be cut if |
| 2191 * the regulator API is in use. | 2191 * the regulator API is in use. |
| 2192 */ | 2192 */ |
| 2193 codec->cache_sync = 1; | 2193 codec->cache_sync = 1; |
| 2194 #endif | 2194 #endif |
| 2195 | 2195 |
| 2196 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), | 2196 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), |
| 2197 wm8904->supplies); | 2197 wm8904->supplies); |
| 2198 break; | 2198 break; |
| 2199 } | 2199 } |
| 2200 » codec->bias_level = level; | 2200 » codec->dapm.bias_level = level; |
| 2201 return 0; | 2201 return 0; |
| 2202 } | 2202 } |
| 2203 | 2203 |
| 2204 #define WM8904_RATES SNDRV_PCM_RATE_8000_96000 | 2204 #define WM8904_RATES SNDRV_PCM_RATE_8000_96000 |
| 2205 | 2205 |
| 2206 #define WM8904_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ | 2206 #define WM8904_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ |
| 2207 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) | 2207 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) |
| 2208 | 2208 |
| 2209 static struct snd_soc_dai_ops wm8904_dai_ops = { | 2209 static struct snd_soc_dai_ops wm8904_dai_ops = { |
| 2210 .set_sysclk = wm8904_set_sysclk, | 2210 .set_sysclk = wm8904_set_sysclk, |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2366 | 2366 |
| 2367 | 2367 |
| 2368 static int wm8904_probe(struct snd_soc_codec *codec) | 2368 static int wm8904_probe(struct snd_soc_codec *codec) |
| 2369 { | 2369 { |
| 2370 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); | 2370 struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); |
| 2371 struct wm8904_pdata *pdata = wm8904->pdata; | 2371 struct wm8904_pdata *pdata = wm8904->pdata; |
| 2372 u16 *reg_cache = codec->reg_cache; | 2372 u16 *reg_cache = codec->reg_cache; |
| 2373 int ret, i; | 2373 int ret, i; |
| 2374 | 2374 |
| 2375 codec->cache_sync = 1; | 2375 codec->cache_sync = 1; |
| 2376 » codec->idle_bias_off = 1; | 2376 » codec->dapm.idle_bias_off = 1; |
| 2377 | 2377 |
| 2378 switch (wm8904->devtype) { | 2378 switch (wm8904->devtype) { |
| 2379 case WM8904: | 2379 case WM8904: |
| 2380 break; | 2380 break; |
| 2381 case WM8912: | 2381 case WM8912: |
| 2382 memset(&wm8904_dai.capture, 0, sizeof(wm8904_dai.capture)); | 2382 memset(&wm8904_dai.capture, 0, sizeof(wm8904_dai.capture)); |
| 2383 break; | 2383 break; |
| 2384 default: | 2384 default: |
| 2385 dev_err(codec->dev, "Unknown device type %d\n", | 2385 dev_err(codec->dev, "Unknown device type %d\n", |
| 2386 wm8904->devtype); | 2386 wm8904->devtype); |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2429 } | 2429 } |
| 2430 dev_info(codec->dev, "revision %c\n", ret + 'A'); | 2430 dev_info(codec->dev, "revision %c\n", ret + 'A'); |
| 2431 | 2431 |
| 2432 ret = wm8904_reset(codec); | 2432 ret = wm8904_reset(codec); |
| 2433 if (ret < 0) { | 2433 if (ret < 0) { |
| 2434 dev_err(codec->dev, "Failed to issue reset\n"); | 2434 dev_err(codec->dev, "Failed to issue reset\n"); |
| 2435 goto err_enable; | 2435 goto err_enable; |
| 2436 } | 2436 } |
| 2437 | 2437 |
| 2438 /* Change some default settings - latch VU and enable ZC */ | 2438 /* Change some default settings - latch VU and enable ZC */ |
| 2439 » reg_cache[WM8904_ADC_DIGITAL_VOLUME_LEFT] |= WM8904_ADC_VU; | 2439 » snd_soc_update_bits(codec, WM8904_ADC_DIGITAL_VOLUME_LEFT, |
| 2440 » reg_cache[WM8904_ADC_DIGITAL_VOLUME_RIGHT] |= WM8904_ADC_VU; | 2440 » » » WM8904_ADC_VU, WM8904_ADC_VU); |
| 2441 » reg_cache[WM8904_DAC_DIGITAL_VOLUME_LEFT] |= WM8904_DAC_VU; | 2441 » snd_soc_update_bits(codec, WM8904_ADC_DIGITAL_VOLUME_RIGHT, |
| 2442 » reg_cache[WM8904_DAC_DIGITAL_VOLUME_RIGHT] |= WM8904_DAC_VU; | 2442 » » » WM8904_ADC_VU, WM8904_ADC_VU); |
| 2443 » reg_cache[WM8904_ANALOGUE_OUT1_LEFT] |= WM8904_HPOUT_VU | | 2443 » snd_soc_update_bits(codec, WM8904_DAC_DIGITAL_VOLUME_LEFT, |
| 2444 » » WM8904_HPOUTLZC; | 2444 » » » WM8904_DAC_VU, WM8904_DAC_VU); |
| 2445 » reg_cache[WM8904_ANALOGUE_OUT1_RIGHT] |= WM8904_HPOUT_VU | | 2445 » snd_soc_update_bits(codec, WM8904_DAC_DIGITAL_VOLUME_RIGHT, |
| 2446 » » WM8904_HPOUTRZC; | 2446 » » » WM8904_DAC_VU, WM8904_DAC_VU); |
| 2447 » reg_cache[WM8904_ANALOGUE_OUT2_LEFT] |= WM8904_LINEOUT_VU | | 2447 » snd_soc_update_bits(codec, WM8904_ANALOGUE_OUT1_LEFT, |
| 2448 » » WM8904_LINEOUTLZC; | 2448 » » » WM8904_HPOUT_VU | WM8904_HPOUTLZC, |
| 2449 » reg_cache[WM8904_ANALOGUE_OUT2_RIGHT] |= WM8904_LINEOUT_VU | | 2449 » » » WM8904_HPOUT_VU | WM8904_HPOUTLZC); |
| 2450 » » WM8904_LINEOUTRZC; | 2450 » snd_soc_update_bits(codec, WM8904_ANALOGUE_OUT1_RIGHT, |
| 2451 » reg_cache[WM8904_CLOCK_RATES_0] &= ~WM8904_SR_MODE; | 2451 » » » WM8904_HPOUT_VU | WM8904_HPOUTRZC, |
| 2452 » » » WM8904_HPOUT_VU | WM8904_HPOUTRZC); |
| 2453 » snd_soc_update_bits(codec, WM8904_ANALOGUE_OUT2_LEFT, |
| 2454 » » » WM8904_LINEOUT_VU | WM8904_LINEOUTLZC, |
| 2455 » » » WM8904_LINEOUT_VU | WM8904_LINEOUTLZC); |
| 2456 » snd_soc_update_bits(codec, WM8904_ANALOGUE_OUT2_RIGHT, |
| 2457 » » » WM8904_LINEOUT_VU | WM8904_LINEOUTRZC, |
| 2458 » » » WM8904_LINEOUT_VU | WM8904_LINEOUTRZC); |
| 2459 » snd_soc_update_bits(codec, WM8904_CLOCK_RATES_0, |
| 2460 » » » WM8904_SR_MODE, 0); |
| 2452 | 2461 |
| 2453 /* Apply configuration from the platform data. */ | 2462 /* Apply configuration from the platform data. */ |
| 2454 if (wm8904->pdata) { | 2463 if (wm8904->pdata) { |
| 2455 for (i = 0; i < WM8904_GPIO_REGS; i++) { | 2464 for (i = 0; i < WM8904_GPIO_REGS; i++) { |
| 2456 if (!pdata->gpio_cfg[i]) | 2465 if (!pdata->gpio_cfg[i]) |
| 2457 continue; | 2466 continue; |
| 2458 | 2467 |
| 2459 reg_cache[WM8904_GPIO_CONTROL_1 + i] | 2468 reg_cache[WM8904_GPIO_CONTROL_1 + i] |
| 2460 = pdata->gpio_cfg[i] & 0xffff; | 2469 = pdata->gpio_cfg[i] & 0xffff; |
| 2461 } | 2470 } |
| 2462 | 2471 |
| 2463 /* Zero is the default value for these anyway */ | 2472 /* Zero is the default value for these anyway */ |
| 2464 for (i = 0; i < WM8904_MIC_REGS; i++) | 2473 for (i = 0; i < WM8904_MIC_REGS; i++) |
| 2465 reg_cache[WM8904_MIC_BIAS_CONTROL_0 + i] | 2474 reg_cache[WM8904_MIC_BIAS_CONTROL_0 + i] |
| 2466 = pdata->mic_cfg[i]; | 2475 = pdata->mic_cfg[i]; |
| 2467 } | 2476 } |
| 2468 | 2477 |
| 2469 /* Set Class W by default - this will be managed by the Class | 2478 /* Set Class W by default - this will be managed by the Class |
| 2470 * G widget at runtime where bypass paths are available. | 2479 * G widget at runtime where bypass paths are available. |
| 2471 */ | 2480 */ |
| 2472 » reg_cache[WM8904_CLASS_W_0] |= WM8904_CP_DYN_PWR; | 2481 » snd_soc_update_bits(codec, WM8904_CLASS_W_0, |
| 2482 » » » WM8904_CP_DYN_PWR, WM8904_CP_DYN_PWR); |
| 2473 | 2483 |
| 2474 /* Use normal bias source */ | 2484 /* Use normal bias source */ |
| 2475 » reg_cache[WM8904_BIAS_CONTROL_0] &= ~WM8904_POBCTRL; | 2485 » snd_soc_update_bits(codec, WM8904_BIAS_CONTROL_0, |
| 2486 » » » WM8904_POBCTRL, 0); |
| 2476 | 2487 |
| 2477 wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 2488 wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
| 2478 | 2489 |
| 2479 /* Bias level configuration will have done an extra enable */ | 2490 /* Bias level configuration will have done an extra enable */ |
| 2480 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); | 2491 regulator_bulk_disable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); |
| 2481 | 2492 |
| 2482 wm8904_handle_pdata(codec); | 2493 wm8904_handle_pdata(codec); |
| 2483 | 2494 |
| 2484 wm8904_add_widgets(codec); | 2495 wm8904_add_widgets(codec); |
| 2485 | 2496 |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2582 { | 2593 { |
| 2583 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 2594 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
| 2584 i2c_del_driver(&wm8904_i2c_driver); | 2595 i2c_del_driver(&wm8904_i2c_driver); |
| 2585 #endif | 2596 #endif |
| 2586 } | 2597 } |
| 2587 module_exit(wm8904_exit); | 2598 module_exit(wm8904_exit); |
| 2588 | 2599 |
| 2589 MODULE_DESCRIPTION("ASoC WM8904 driver"); | 2600 MODULE_DESCRIPTION("ASoC WM8904 driver"); |
| 2590 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); | 2601 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); |
| 2591 MODULE_LICENSE("GPL"); | 2602 MODULE_LICENSE("GPL"); |
| OLD | NEW |