wm8993.c (cf0dbba515415bb19b11f9323d5f7bebd7f24fd6) | wm8993.c (b2c812e22de88bb79c290c0e718280f10b64a48d) |
---|---|
1/* 2 * wm8993.c -- WM8993 ALSA SoC audio driver 3 * 4 * Copyright 2009, 2010 Wolfson Microelectronics plc 5 * 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 7 * 8 * This program is free software; you can redistribute it and/or modify --- 4 unchanged lines hidden (view full) --- 13#include <linux/module.h> 14#include <linux/moduleparam.h> 15#include <linux/init.h> 16#include <linux/delay.h> 17#include <linux/pm.h> 18#include <linux/i2c.h> 19#include <linux/regulator/consumer.h> 20#include <linux/spi/spi.h> | 1/* 2 * wm8993.c -- WM8993 ALSA SoC audio driver 3 * 4 * Copyright 2009, 2010 Wolfson Microelectronics plc 5 * 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 7 * 8 * This program is free software; you can redistribute it and/or modify --- 4 unchanged lines hidden (view full) --- 13#include <linux/module.h> 14#include <linux/moduleparam.h> 15#include <linux/init.h> 16#include <linux/delay.h> 17#include <linux/pm.h> 18#include <linux/i2c.h> 19#include <linux/regulator/consumer.h> 20#include <linux/spi/spi.h> |
21#include <linux/slab.h> | |
22#include <sound/core.h> 23#include <sound/pcm.h> 24#include <sound/pcm_params.h> 25#include <sound/tlv.h> 26#include <sound/soc.h> 27#include <sound/soc-dapm.h> 28#include <sound/initval.h> 29#include <sound/wm8993.h> --- 336 unchanged lines hidden (view full) --- 366 367 return 0; 368} 369 370static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id, int source, 371 unsigned int Fref, unsigned int Fout) 372{ 373 struct snd_soc_codec *codec = dai->codec; | 21#include <sound/core.h> 22#include <sound/pcm.h> 23#include <sound/pcm_params.h> 24#include <sound/tlv.h> 25#include <sound/soc.h> 26#include <sound/soc-dapm.h> 27#include <sound/initval.h> 28#include <sound/wm8993.h> --- 336 unchanged lines hidden (view full) --- 365 366 return 0; 367} 368 369static int wm8993_set_fll(struct snd_soc_dai *dai, int fll_id, int source, 370 unsigned int Fref, unsigned int Fout) 371{ 372 struct snd_soc_codec *codec = dai->codec; |
374 struct wm8993_priv *wm8993 = codec->private_data; | 373 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); |
375 u16 reg1, reg4, reg5; 376 struct _fll_div fll_div; 377 int ret; 378 379 /* Any change? */ 380 if (Fref == wm8993->fll_fref && Fout == wm8993->fll_fout) 381 return 0; 382 --- 70 unchanged lines hidden (view full) --- 453 wm8993->fll_fout = Fout; 454 wm8993->fll_src = source; 455 456 return 0; 457} 458 459static int configure_clock(struct snd_soc_codec *codec) 460{ | 374 u16 reg1, reg4, reg5; 375 struct _fll_div fll_div; 376 int ret; 377 378 /* Any change? */ 379 if (Fref == wm8993->fll_fref && Fout == wm8993->fll_fout) 380 return 0; 381 --- 70 unchanged lines hidden (view full) --- 452 wm8993->fll_fout = Fout; 453 wm8993->fll_src = source; 454 455 return 0; 456} 457 458static int configure_clock(struct snd_soc_codec *codec) 459{ |
461 struct wm8993_priv *wm8993 = codec->private_data; | 460 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); |
462 unsigned int reg; 463 464 /* This should be done on init() for bypass paths */ 465 switch (wm8993->sysclk_source) { 466 case WM8993_SYSCLK_MCLK: 467 dev_dbg(codec->dev, "Using %dHz MCLK\n", wm8993->mclk_rate); 468 469 reg = snd_soc_read(codec, WM8993_CLOCKING_2); --- 242 unchanged lines hidden (view full) --- 712 * Currently the only supported paths are the direct DAC->headphone 713 * paths (which provide minimum power consumption anyway). 714 */ 715static int class_w_put(struct snd_kcontrol *kcontrol, 716 struct snd_ctl_elem_value *ucontrol) 717{ 718 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 719 struct snd_soc_codec *codec = widget->codec; | 461 unsigned int reg; 462 463 /* This should be done on init() for bypass paths */ 464 switch (wm8993->sysclk_source) { 465 case WM8993_SYSCLK_MCLK: 466 dev_dbg(codec->dev, "Using %dHz MCLK\n", wm8993->mclk_rate); 467 468 reg = snd_soc_read(codec, WM8993_CLOCKING_2); --- 242 unchanged lines hidden (view full) --- 711 * Currently the only supported paths are the direct DAC->headphone 712 * paths (which provide minimum power consumption anyway). 713 */ 714static int class_w_put(struct snd_kcontrol *kcontrol, 715 struct snd_ctl_elem_value *ucontrol) 716{ 717 struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); 718 struct snd_soc_codec *codec = widget->codec; |
720 struct wm8993_priv *wm8993 = codec->private_data; | 719 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); |
721 int ret; 722 723 /* Turn it off if we're using the main output mixer */ 724 if (ucontrol->value.integer.value[0] == 0) { 725 if (wm8993->class_w_users == 0) { 726 dev_dbg(codec->dev, "Disabling Class W\n"); 727 snd_soc_update_bits(codec, WM8993_CLASS_W_0, 728 WM8993_CP_DYN_FREQ | --- 215 unchanged lines hidden (view full) --- 944 945 /* We're in sync again */ 946 codec->cache_sync = 0; 947} 948 949static int wm8993_set_bias_level(struct snd_soc_codec *codec, 950 enum snd_soc_bias_level level) 951{ | 720 int ret; 721 722 /* Turn it off if we're using the main output mixer */ 723 if (ucontrol->value.integer.value[0] == 0) { 724 if (wm8993->class_w_users == 0) { 725 dev_dbg(codec->dev, "Disabling Class W\n"); 726 snd_soc_update_bits(codec, WM8993_CLASS_W_0, 727 WM8993_CP_DYN_FREQ | --- 215 unchanged lines hidden (view full) --- 943 944 /* We're in sync again */ 945 codec->cache_sync = 0; 946} 947 948static int wm8993_set_bias_level(struct snd_soc_codec *codec, 949 enum snd_soc_bias_level level) 950{ |
952 struct wm8993_priv *wm8993 = codec->private_data; | 951 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); |
953 int ret; 954 955 switch (level) { 956 case SND_SOC_BIAS_ON: 957 case SND_SOC_BIAS_PREPARE: 958 /* VMID=2*40k */ 959 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1, 960 WM8993_VMID_SEL_MASK, 0x2); --- 81 unchanged lines hidden (view full) --- 1042 1043 return 0; 1044} 1045 1046static int wm8993_set_sysclk(struct snd_soc_dai *codec_dai, 1047 int clk_id, unsigned int freq, int dir) 1048{ 1049 struct snd_soc_codec *codec = codec_dai->codec; | 952 int ret; 953 954 switch (level) { 955 case SND_SOC_BIAS_ON: 956 case SND_SOC_BIAS_PREPARE: 957 /* VMID=2*40k */ 958 snd_soc_update_bits(codec, WM8993_POWER_MANAGEMENT_1, 959 WM8993_VMID_SEL_MASK, 0x2); --- 81 unchanged lines hidden (view full) --- 1041 1042 return 0; 1043} 1044 1045static int wm8993_set_sysclk(struct snd_soc_dai *codec_dai, 1046 int clk_id, unsigned int freq, int dir) 1047{ 1048 struct snd_soc_codec *codec = codec_dai->codec; |
1050 struct wm8993_priv *wm8993 = codec->private_data; | 1049 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); |
1051 1052 switch (clk_id) { 1053 case WM8993_SYSCLK_MCLK: 1054 wm8993->mclk_rate = freq; 1055 case WM8993_SYSCLK_FLL: 1056 wm8993->sysclk_source = clk_id; 1057 break; 1058 1059 default: 1060 return -EINVAL; 1061 } 1062 1063 return 0; 1064} 1065 1066static int wm8993_set_dai_fmt(struct snd_soc_dai *dai, 1067 unsigned int fmt) 1068{ 1069 struct snd_soc_codec *codec = dai->codec; | 1050 1051 switch (clk_id) { 1052 case WM8993_SYSCLK_MCLK: 1053 wm8993->mclk_rate = freq; 1054 case WM8993_SYSCLK_FLL: 1055 wm8993->sysclk_source = clk_id; 1056 break; 1057 1058 default: 1059 return -EINVAL; 1060 } 1061 1062 return 0; 1063} 1064 1065static int wm8993_set_dai_fmt(struct snd_soc_dai *dai, 1066 unsigned int fmt) 1067{ 1068 struct snd_soc_codec *codec = dai->codec; |
1070 struct wm8993_priv *wm8993 = codec->private_data; | 1069 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); |
1071 unsigned int aif1 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_1); 1072 unsigned int aif4 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_4); 1073 1074 aif1 &= ~(WM8993_BCLK_DIR | WM8993_AIF_BCLK_INV | 1075 WM8993_AIF_LRCLK_INV | WM8993_AIF_FMT_MASK); 1076 aif4 &= ~WM8993_LRCLK_DIR; 1077 1078 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { --- 79 unchanged lines hidden (view full) --- 1158 return 0; 1159} 1160 1161static int wm8993_hw_params(struct snd_pcm_substream *substream, 1162 struct snd_pcm_hw_params *params, 1163 struct snd_soc_dai *dai) 1164{ 1165 struct snd_soc_codec *codec = dai->codec; | 1070 unsigned int aif1 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_1); 1071 unsigned int aif4 = snd_soc_read(codec, WM8993_AUDIO_INTERFACE_4); 1072 1073 aif1 &= ~(WM8993_BCLK_DIR | WM8993_AIF_BCLK_INV | 1074 WM8993_AIF_LRCLK_INV | WM8993_AIF_FMT_MASK); 1075 aif4 &= ~WM8993_LRCLK_DIR; 1076 1077 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { --- 79 unchanged lines hidden (view full) --- 1157 return 0; 1158} 1159 1160static int wm8993_hw_params(struct snd_pcm_substream *substream, 1161 struct snd_pcm_hw_params *params, 1162 struct snd_soc_dai *dai) 1163{ 1164 struct snd_soc_codec *codec = dai->codec; |
1166 struct wm8993_priv *wm8993 = codec->private_data; | 1165 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); |
1167 int ret, i, best, best_val, cur_val; 1168 unsigned int clocking1, clocking3, aif1, aif4; 1169 1170 clocking1 = snd_soc_read(codec, WM8993_CLOCKING_1); 1171 clocking1 &= ~WM8993_BCLK_DIV_MASK; 1172 1173 clocking3 = snd_soc_read(codec, WM8993_CLOCKING_3); 1174 clocking3 &= ~(WM8993_CLK_SYS_RATE_MASK | WM8993_SAMPLE_RATE_MASK); --- 148 unchanged lines hidden (view full) --- 1323 1324 return 0; 1325} 1326 1327static int wm8993_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, 1328 unsigned int rx_mask, int slots, int slot_width) 1329{ 1330 struct snd_soc_codec *codec = dai->codec; | 1166 int ret, i, best, best_val, cur_val; 1167 unsigned int clocking1, clocking3, aif1, aif4; 1168 1169 clocking1 = snd_soc_read(codec, WM8993_CLOCKING_1); 1170 clocking1 &= ~WM8993_BCLK_DIV_MASK; 1171 1172 clocking3 = snd_soc_read(codec, WM8993_CLOCKING_3); 1173 clocking3 &= ~(WM8993_CLK_SYS_RATE_MASK | WM8993_SAMPLE_RATE_MASK); --- 148 unchanged lines hidden (view full) --- 1322 1323 return 0; 1324} 1325 1326static int wm8993_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, 1327 unsigned int rx_mask, int slots, int slot_width) 1328{ 1329 struct snd_soc_codec *codec = dai->codec; |
1331 struct wm8993_priv *wm8993 = codec->private_data; | 1330 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); |
1332 int aif1 = 0; 1333 int aif2 = 0; 1334 1335 /* Don't need to validate anything if we're turning off TDM */ 1336 if (slots == 0) { 1337 wm8993->tdm_slots = 0; 1338 goto out; 1339 } --- 86 unchanged lines hidden (view full) --- 1426 1427 if (!wm8993_codec) { 1428 dev_err(&pdev->dev, "I2C device not yet probed\n"); 1429 goto err; 1430 } 1431 1432 socdev->card->codec = wm8993_codec; 1433 codec = wm8993_codec; | 1331 int aif1 = 0; 1332 int aif2 = 0; 1333 1334 /* Don't need to validate anything if we're turning off TDM */ 1335 if (slots == 0) { 1336 wm8993->tdm_slots = 0; 1337 goto out; 1338 } --- 86 unchanged lines hidden (view full) --- 1425 1426 if (!wm8993_codec) { 1427 dev_err(&pdev->dev, "I2C device not yet probed\n"); 1428 goto err; 1429 } 1430 1431 socdev->card->codec = wm8993_codec; 1432 codec = wm8993_codec; |
1434 wm8993 = codec->private_data; | 1433 wm8993 = snd_soc_codec_get_drvdata(codec); |
1435 1436 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 1437 if (ret < 0) { 1438 dev_err(codec->dev, "failed to create pcms\n"); 1439 goto err; 1440 } 1441 1442 snd_soc_add_controls(codec, wm8993_snd_controls, --- 30 unchanged lines hidden (view full) --- 1473 return 0; 1474} 1475 1476#ifdef CONFIG_PM 1477static int wm8993_suspend(struct platform_device *pdev, pm_message_t state) 1478{ 1479 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1480 struct snd_soc_codec *codec = socdev->card->codec; | 1434 1435 ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); 1436 if (ret < 0) { 1437 dev_err(codec->dev, "failed to create pcms\n"); 1438 goto err; 1439 } 1440 1441 snd_soc_add_controls(codec, wm8993_snd_controls, --- 30 unchanged lines hidden (view full) --- 1472 return 0; 1473} 1474 1475#ifdef CONFIG_PM 1476static int wm8993_suspend(struct platform_device *pdev, pm_message_t state) 1477{ 1478 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1479 struct snd_soc_codec *codec = socdev->card->codec; |
1481 struct wm8993_priv *wm8993 = codec->private_data; | 1480 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); |
1482 int fll_fout = wm8993->fll_fout; 1483 int fll_fref = wm8993->fll_fref; 1484 int ret; 1485 1486 /* Stop the FLL in an orderly fashion */ 1487 ret = wm8993_set_fll(codec->dai, 0, 0, 0, 0); 1488 if (ret != 0) { 1489 dev_err(&pdev->dev, "Failed to stop FLL\n"); --- 7 unchanged lines hidden (view full) --- 1497 1498 return 0; 1499} 1500 1501static int wm8993_resume(struct platform_device *pdev) 1502{ 1503 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1504 struct snd_soc_codec *codec = socdev->card->codec; | 1481 int fll_fout = wm8993->fll_fout; 1482 int fll_fref = wm8993->fll_fref; 1483 int ret; 1484 1485 /* Stop the FLL in an orderly fashion */ 1486 ret = wm8993_set_fll(codec->dai, 0, 0, 0, 0); 1487 if (ret != 0) { 1488 dev_err(&pdev->dev, "Failed to stop FLL\n"); --- 7 unchanged lines hidden (view full) --- 1496 1497 return 0; 1498} 1499 1500static int wm8993_resume(struct platform_device *pdev) 1501{ 1502 struct snd_soc_device *socdev = platform_get_drvdata(pdev); 1503 struct snd_soc_codec *codec = socdev->card->codec; |
1505 struct wm8993_priv *wm8993 = codec->private_data; | 1504 struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); |
1506 int ret; 1507 1508 wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1509 1510 /* Restart the FLL? */ 1511 if (wm8993->fll_fout) { 1512 int fll_fout = wm8993->fll_fout; 1513 int fll_fref = wm8993->fll_fref; --- 52 unchanged lines hidden (view full) --- 1566 codec->name = "WM8993"; 1567 codec->volatile_register = wm8993_volatile; 1568 codec->reg_cache = wm8993->reg_cache; 1569 codec->reg_cache_size = ARRAY_SIZE(wm8993->reg_cache); 1570 codec->bias_level = SND_SOC_BIAS_OFF; 1571 codec->set_bias_level = wm8993_set_bias_level; 1572 codec->dai = &wm8993_dai; 1573 codec->num_dai = 1; | 1505 int ret; 1506 1507 wm8993_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1508 1509 /* Restart the FLL? */ 1510 if (wm8993->fll_fout) { 1511 int fll_fout = wm8993->fll_fout; 1512 int fll_fref = wm8993->fll_fref; --- 52 unchanged lines hidden (view full) --- 1565 codec->name = "WM8993"; 1566 codec->volatile_register = wm8993_volatile; 1567 codec->reg_cache = wm8993->reg_cache; 1568 codec->reg_cache_size = ARRAY_SIZE(wm8993->reg_cache); 1569 codec->bias_level = SND_SOC_BIAS_OFF; 1570 codec->set_bias_level = wm8993_set_bias_level; 1571 codec->dai = &wm8993_dai; 1572 codec->num_dai = 1; |
1574 codec->private_data = wm8993; | 1573 snd_soc_codec_set_drvdata(codec, wm8993); |
1575 1576 wm8993->hubs_data.hp_startup_mode = 1; 1577 wm8993->hubs_data.dcs_codes = -2; 1578 1579 memcpy(wm8993->reg_cache, wm8993_reg_defaults, 1580 sizeof(wm8993->reg_cache)); 1581 1582 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); --- 146 unchanged lines hidden --- | 1574 1575 wm8993->hubs_data.hp_startup_mode = 1; 1576 wm8993->hubs_data.dcs_codes = -2; 1577 1578 memcpy(wm8993->reg_cache, wm8993_reg_defaults, 1579 sizeof(wm8993->reg_cache)); 1580 1581 ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); --- 146 unchanged lines hidden --- |