diff options
author | Takashi Iwai <tiwai@suse.de> | 2010-05-20 06:00:43 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2010-05-20 06:00:43 -0400 |
commit | d71f4cece4bd97d05592836202fc04ff2e7817e3 (patch) | |
tree | 6c877c7a938758b1323d9c97d46b9c536e618c69 /sound/soc/codecs/wm8350.c | |
parent | 19008bdacb9f7841166ebafe0aef361ee582ffbf (diff) | |
parent | ad8332c1302bcb4f80d593fd3eb477be9d7f5604 (diff) |
Merge branch 'topic/asoc' into for-linus
Conflicts:
sound/soc/codecs/ad1938.c
Diffstat (limited to 'sound/soc/codecs/wm8350.c')
-rw-r--r-- | sound/soc/codecs/wm8350.c | 103 |
1 files changed, 84 insertions, 19 deletions
diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index 2e0772f9c45..8ae20208e7b 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c | |||
@@ -55,6 +55,7 @@ struct wm8350_output { | |||
55 | struct wm8350_jack_data { | 55 | struct wm8350_jack_data { |
56 | struct snd_soc_jack *jack; | 56 | struct snd_soc_jack *jack; |
57 | int report; | 57 | int report; |
58 | int short_report; | ||
58 | }; | 59 | }; |
59 | 60 | ||
60 | struct wm8350_data { | 61 | struct wm8350_data { |
@@ -63,6 +64,7 @@ struct wm8350_data { | |||
63 | struct wm8350_output out2; | 64 | struct wm8350_output out2; |
64 | struct wm8350_jack_data hpl; | 65 | struct wm8350_jack_data hpl; |
65 | struct wm8350_jack_data hpr; | 66 | struct wm8350_jack_data hpr; |
67 | struct wm8350_jack_data mic; | ||
66 | struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)]; | 68 | struct regulator_bulk_data supplies[ARRAY_SIZE(supply_names)]; |
67 | int fll_freq_out; | 69 | int fll_freq_out; |
68 | int fll_freq_in; | 70 | int fll_freq_in; |
@@ -94,7 +96,7 @@ static int wm8350_codec_write(struct snd_soc_codec *codec, unsigned int reg, | |||
94 | */ | 96 | */ |
95 | static inline int wm8350_out1_ramp_step(struct snd_soc_codec *codec) | 97 | static inline int wm8350_out1_ramp_step(struct snd_soc_codec *codec) |
96 | { | 98 | { |
97 | struct wm8350_data *wm8350_data = codec->private_data; | 99 | struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec); |
98 | struct wm8350_output *out1 = &wm8350_data->out1; | 100 | struct wm8350_output *out1 = &wm8350_data->out1; |
99 | struct wm8350 *wm8350 = codec->control_data; | 101 | struct wm8350 *wm8350 = codec->control_data; |
100 | int left_complete = 0, right_complete = 0; | 102 | int left_complete = 0, right_complete = 0; |
@@ -160,7 +162,7 @@ static inline int wm8350_out1_ramp_step(struct snd_soc_codec *codec) | |||
160 | */ | 162 | */ |
161 | static inline int wm8350_out2_ramp_step(struct snd_soc_codec *codec) | 163 | static inline int wm8350_out2_ramp_step(struct snd_soc_codec *codec) |
162 | { | 164 | { |
163 | struct wm8350_data *wm8350_data = codec->private_data; | 165 | struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec); |
164 | struct wm8350_output *out2 = &wm8350_data->out2; | 166 | struct wm8350_output *out2 = &wm8350_data->out2; |
165 | struct wm8350 *wm8350 = codec->control_data; | 167 | struct wm8350 *wm8350 = codec->control_data; |
166 | int left_complete = 0, right_complete = 0; | 168 | int left_complete = 0, right_complete = 0; |
@@ -230,7 +232,7 @@ static void wm8350_pga_work(struct work_struct *work) | |||
230 | { | 232 | { |
231 | struct snd_soc_codec *codec = | 233 | struct snd_soc_codec *codec = |
232 | container_of(work, struct snd_soc_codec, delayed_work.work); | 234 | container_of(work, struct snd_soc_codec, delayed_work.work); |
233 | struct wm8350_data *wm8350_data = codec->private_data; | 235 | struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec); |
234 | struct wm8350_output *out1 = &wm8350_data->out1, | 236 | struct wm8350_output *out1 = &wm8350_data->out1, |
235 | *out2 = &wm8350_data->out2; | 237 | *out2 = &wm8350_data->out2; |
236 | int i, out1_complete, out2_complete; | 238 | int i, out1_complete, out2_complete; |
@@ -277,7 +279,7 @@ static int pga_event(struct snd_soc_dapm_widget *w, | |||
277 | struct snd_kcontrol *kcontrol, int event) | 279 | struct snd_kcontrol *kcontrol, int event) |
278 | { | 280 | { |
279 | struct snd_soc_codec *codec = w->codec; | 281 | struct snd_soc_codec *codec = w->codec; |
280 | struct wm8350_data *wm8350_data = codec->private_data; | 282 | struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec); |
281 | struct wm8350_output *out; | 283 | struct wm8350_output *out; |
282 | 284 | ||
283 | switch (w->shift) { | 285 | switch (w->shift) { |
@@ -322,7 +324,7 @@ static int wm8350_put_volsw_2r_vu(struct snd_kcontrol *kcontrol, | |||
322 | struct snd_ctl_elem_value *ucontrol) | 324 | struct snd_ctl_elem_value *ucontrol) |
323 | { | 325 | { |
324 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 326 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
325 | struct wm8350_data *wm8350_priv = codec->private_data; | 327 | struct wm8350_data *wm8350_priv = snd_soc_codec_get_drvdata(codec); |
326 | struct wm8350_output *out = NULL; | 328 | struct wm8350_output *out = NULL; |
327 | struct soc_mixer_control *mc = | 329 | struct soc_mixer_control *mc = |
328 | (struct soc_mixer_control *)kcontrol->private_value; | 330 | (struct soc_mixer_control *)kcontrol->private_value; |
@@ -365,7 +367,7 @@ static int wm8350_get_volsw_2r(struct snd_kcontrol *kcontrol, | |||
365 | struct snd_ctl_elem_value *ucontrol) | 367 | struct snd_ctl_elem_value *ucontrol) |
366 | { | 368 | { |
367 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 369 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
368 | struct wm8350_data *wm8350_priv = codec->private_data; | 370 | struct wm8350_data *wm8350_priv = snd_soc_codec_get_drvdata(codec); |
369 | struct wm8350_output *out1 = &wm8350_priv->out1; | 371 | struct wm8350_output *out1 = &wm8350_priv->out1; |
370 | struct wm8350_output *out2 = &wm8350_priv->out2; | 372 | struct wm8350_output *out2 = &wm8350_priv->out2; |
371 | struct soc_mixer_control *mc = | 373 | struct soc_mixer_control *mc = |
@@ -1107,7 +1109,7 @@ static int wm8350_set_fll(struct snd_soc_dai *codec_dai, | |||
1107 | { | 1109 | { |
1108 | struct snd_soc_codec *codec = codec_dai->codec; | 1110 | struct snd_soc_codec *codec = codec_dai->codec; |
1109 | struct wm8350 *wm8350 = codec->control_data; | 1111 | struct wm8350 *wm8350 = codec->control_data; |
1110 | struct wm8350_data *priv = codec->private_data; | 1112 | struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec); |
1111 | struct _fll_div fll_div; | 1113 | struct _fll_div fll_div; |
1112 | int ret = 0; | 1114 | int ret = 0; |
1113 | u16 fll_1, fll_4; | 1115 | u16 fll_1, fll_4; |
@@ -1159,7 +1161,7 @@ static int wm8350_set_bias_level(struct snd_soc_codec *codec, | |||
1159 | enum snd_soc_bias_level level) | 1161 | enum snd_soc_bias_level level) |
1160 | { | 1162 | { |
1161 | struct wm8350 *wm8350 = codec->control_data; | 1163 | struct wm8350 *wm8350 = codec->control_data; |
1162 | struct wm8350_data *priv = codec->private_data; | 1164 | struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec); |
1163 | struct wm8350_audio_platform_data *platform = | 1165 | struct wm8350_audio_platform_data *platform = |
1164 | wm8350->codec.platform_data; | 1166 | wm8350->codec.platform_data; |
1165 | u16 pm1; | 1167 | u16 pm1; |
@@ -1335,9 +1337,6 @@ static int wm8350_resume(struct platform_device *pdev) | |||
1335 | 1337 | ||
1336 | wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 1338 | wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
1337 | 1339 | ||
1338 | if (codec->suspend_bias_level == SND_SOC_BIAS_ON) | ||
1339 | wm8350_set_bias_level(codec, SND_SOC_BIAS_ON); | ||
1340 | |||
1341 | return 0; | 1340 | return 0; |
1342 | } | 1341 | } |
1343 | 1342 | ||
@@ -1392,12 +1391,13 @@ static irqreturn_t wm8350_hp_jack_handler(int irq, void *data) | |||
1392 | * @jack: jack to report detection events on | 1391 | * @jack: jack to report detection events on |
1393 | * @report: value to report | 1392 | * @report: value to report |
1394 | * | 1393 | * |
1395 | * Enables the headphone jack detection of the WM8350. | 1394 | * Enables the headphone jack detection of the WM8350. If no report |
1395 | * is specified then detection is disabled. | ||
1396 | */ | 1396 | */ |
1397 | int wm8350_hp_jack_detect(struct snd_soc_codec *codec, enum wm8350_jack which, | 1397 | int wm8350_hp_jack_detect(struct snd_soc_codec *codec, enum wm8350_jack which, |
1398 | struct snd_soc_jack *jack, int report) | 1398 | struct snd_soc_jack *jack, int report) |
1399 | { | 1399 | { |
1400 | struct wm8350_data *priv = codec->private_data; | 1400 | struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec); |
1401 | struct wm8350 *wm8350 = codec->control_data; | 1401 | struct wm8350 *wm8350 = codec->control_data; |
1402 | int irq; | 1402 | int irq; |
1403 | int ena; | 1403 | int ena; |
@@ -1421,8 +1421,12 @@ int wm8350_hp_jack_detect(struct snd_soc_codec *codec, enum wm8350_jack which, | |||
1421 | return -EINVAL; | 1421 | return -EINVAL; |
1422 | } | 1422 | } |
1423 | 1423 | ||
1424 | wm8350_set_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_TOCLK_ENA); | 1424 | if (report) { |
1425 | wm8350_set_bits(wm8350, WM8350_JACK_DETECT, ena); | 1425 | wm8350_set_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_TOCLK_ENA); |
1426 | wm8350_set_bits(wm8350, WM8350_JACK_DETECT, ena); | ||
1427 | } else { | ||
1428 | wm8350_clear_bits(wm8350, WM8350_JACK_DETECT, ena); | ||
1429 | } | ||
1426 | 1430 | ||
1427 | /* Sync status */ | 1431 | /* Sync status */ |
1428 | wm8350_hp_jack_handler(irq + wm8350->irq_base, priv); | 1432 | wm8350_hp_jack_handler(irq + wm8350->irq_base, priv); |
@@ -1431,6 +1435,60 @@ int wm8350_hp_jack_detect(struct snd_soc_codec *codec, enum wm8350_jack which, | |||
1431 | } | 1435 | } |
1432 | EXPORT_SYMBOL_GPL(wm8350_hp_jack_detect); | 1436 | EXPORT_SYMBOL_GPL(wm8350_hp_jack_detect); |
1433 | 1437 | ||
1438 | static irqreturn_t wm8350_mic_handler(int irq, void *data) | ||
1439 | { | ||
1440 | struct wm8350_data *priv = data; | ||
1441 | struct wm8350 *wm8350 = priv->codec.control_data; | ||
1442 | u16 reg; | ||
1443 | int report = 0; | ||
1444 | |||
1445 | reg = wm8350_reg_read(wm8350, WM8350_JACK_PIN_STATUS); | ||
1446 | if (reg & WM8350_JACK_MICSCD_LVL) | ||
1447 | report |= priv->mic.short_report; | ||
1448 | if (reg & WM8350_JACK_MICSD_LVL) | ||
1449 | report |= priv->mic.report; | ||
1450 | |||
1451 | snd_soc_jack_report(priv->mic.jack, report, | ||
1452 | priv->mic.report | priv->mic.short_report); | ||
1453 | |||
1454 | return IRQ_HANDLED; | ||
1455 | } | ||
1456 | |||
1457 | /** | ||
1458 | * wm8350_mic_jack_detect - Enable microphone jack detection. | ||
1459 | * | ||
1460 | * @codec: WM8350 codec | ||
1461 | * @jack: jack to report detection events on | ||
1462 | * @detect_report: value to report when presence detected | ||
1463 | * @short_report: value to report when microphone short detected | ||
1464 | * | ||
1465 | * Enables the microphone jack detection of the WM8350. If both reports | ||
1466 | * are specified as zero then detection is disabled. | ||
1467 | */ | ||
1468 | int wm8350_mic_jack_detect(struct snd_soc_codec *codec, | ||
1469 | struct snd_soc_jack *jack, | ||
1470 | int detect_report, int short_report) | ||
1471 | { | ||
1472 | struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec); | ||
1473 | struct wm8350 *wm8350 = codec->control_data; | ||
1474 | |||
1475 | priv->mic.jack = jack; | ||
1476 | priv->mic.report = detect_report; | ||
1477 | priv->mic.short_report = short_report; | ||
1478 | |||
1479 | if (detect_report || short_report) { | ||
1480 | wm8350_set_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_TOCLK_ENA); | ||
1481 | wm8350_set_bits(wm8350, WM8350_POWER_MGMT_1, | ||
1482 | WM8350_MIC_DET_ENA); | ||
1483 | } else { | ||
1484 | wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_1, | ||
1485 | WM8350_MIC_DET_ENA); | ||
1486 | } | ||
1487 | |||
1488 | return 0; | ||
1489 | } | ||
1490 | EXPORT_SYMBOL_GPL(wm8350_mic_jack_detect); | ||
1491 | |||
1434 | static struct snd_soc_codec *wm8350_codec; | 1492 | static struct snd_soc_codec *wm8350_codec; |
1435 | 1493 | ||
1436 | static int wm8350_probe(struct platform_device *pdev) | 1494 | static int wm8350_probe(struct platform_device *pdev) |
@@ -1448,7 +1506,7 @@ static int wm8350_probe(struct platform_device *pdev) | |||
1448 | socdev->card->codec = wm8350_codec; | 1506 | socdev->card->codec = wm8350_codec; |
1449 | codec = socdev->card->codec; | 1507 | codec = socdev->card->codec; |
1450 | wm8350 = codec->control_data; | 1508 | wm8350 = codec->control_data; |
1451 | priv = codec->private_data; | 1509 | priv = snd_soc_codec_get_drvdata(codec); |
1452 | 1510 | ||
1453 | /* Enable the codec */ | 1511 | /* Enable the codec */ |
1454 | wm8350_set_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA); | 1512 | wm8350_set_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA); |
@@ -1494,6 +1552,10 @@ static int wm8350_probe(struct platform_device *pdev) | |||
1494 | wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R, | 1552 | wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R, |
1495 | wm8350_hp_jack_handler, 0, "Right jack detect", | 1553 | wm8350_hp_jack_handler, 0, "Right jack detect", |
1496 | priv); | 1554 | priv); |
1555 | wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_MICSCD, | ||
1556 | wm8350_mic_handler, 0, "Microphone short", priv); | ||
1557 | wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_MICD, | ||
1558 | wm8350_mic_handler, 0, "Microphone detect", priv); | ||
1497 | 1559 | ||
1498 | ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); | 1560 | ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); |
1499 | if (ret < 0) { | 1561 | if (ret < 0) { |
@@ -1515,18 +1577,21 @@ static int wm8350_remove(struct platform_device *pdev) | |||
1515 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 1577 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
1516 | struct snd_soc_codec *codec = socdev->card->codec; | 1578 | struct snd_soc_codec *codec = socdev->card->codec; |
1517 | struct wm8350 *wm8350 = codec->control_data; | 1579 | struct wm8350 *wm8350 = codec->control_data; |
1518 | struct wm8350_data *priv = codec->private_data; | 1580 | struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec); |
1519 | int ret; | 1581 | int ret; |
1520 | 1582 | ||
1521 | wm8350_clear_bits(wm8350, WM8350_JACK_DETECT, | 1583 | wm8350_clear_bits(wm8350, WM8350_JACK_DETECT, |
1522 | WM8350_JDL_ENA | WM8350_JDR_ENA); | 1584 | WM8350_JDL_ENA | WM8350_JDR_ENA); |
1523 | wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_TOCLK_ENA); | 1585 | wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_TOCLK_ENA); |
1524 | 1586 | ||
1587 | wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_MICD, priv); | ||
1588 | wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_MICSCD, priv); | ||
1525 | wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L, priv); | 1589 | wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L, priv); |
1526 | wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R, priv); | 1590 | wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R, priv); |
1527 | 1591 | ||
1528 | priv->hpl.jack = NULL; | 1592 | priv->hpl.jack = NULL; |
1529 | priv->hpr.jack = NULL; | 1593 | priv->hpr.jack = NULL; |
1594 | priv->mic.jack = NULL; | ||
1530 | 1595 | ||
1531 | /* cancel any work waiting to be queued. */ | 1596 | /* cancel any work waiting to be queued. */ |
1532 | ret = cancel_delayed_work(&codec->delayed_work); | 1597 | ret = cancel_delayed_work(&codec->delayed_work); |
@@ -1631,7 +1696,7 @@ static __devinit int wm8350_codec_probe(struct platform_device *pdev) | |||
1631 | codec->dai = &wm8350_dai; | 1696 | codec->dai = &wm8350_dai; |
1632 | codec->num_dai = 1; | 1697 | codec->num_dai = 1; |
1633 | codec->reg_cache_size = WM8350_MAX_REGISTER; | 1698 | codec->reg_cache_size = WM8350_MAX_REGISTER; |
1634 | codec->private_data = priv; | 1699 | snd_soc_codec_set_drvdata(codec, priv); |
1635 | codec->control_data = wm8350; | 1700 | codec->control_data = wm8350; |
1636 | 1701 | ||
1637 | /* Put the codec into reset if it wasn't already */ | 1702 | /* Put the codec into reset if it wasn't already */ |
@@ -1663,7 +1728,7 @@ static int __devexit wm8350_codec_remove(struct platform_device *pdev) | |||
1663 | { | 1728 | { |
1664 | struct wm8350 *wm8350 = platform_get_drvdata(pdev); | 1729 | struct wm8350 *wm8350 = platform_get_drvdata(pdev); |
1665 | struct snd_soc_codec *codec = wm8350->codec.codec; | 1730 | struct snd_soc_codec *codec = wm8350->codec.codec; |
1666 | struct wm8350_data *priv = codec->private_data; | 1731 | struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec); |
1667 | 1732 | ||
1668 | snd_soc_unregister_dai(&wm8350_dai); | 1733 | snd_soc_unregister_dai(&wm8350_dai); |
1669 | snd_soc_unregister_codec(codec); | 1734 | snd_soc_unregister_codec(codec); |