aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sound/soc/codecs/88pm860x-codec.c75
-rw-r--r--sound/soc/codecs/88pm860x-codec.h117
2 files changed, 71 insertions, 121 deletions
diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c
index 259d1ac4492f..75d0ad5d2dcb 100644
--- a/sound/soc/codecs/88pm860x-codec.c
+++ b/sound/soc/codecs/88pm860x-codec.c
@@ -16,6 +16,7 @@
16#include <linux/mfd/88pm860x.h> 16#include <linux/mfd/88pm860x.h>
17#include <linux/slab.h> 17#include <linux/slab.h>
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/regmap.h>
19#include <sound/core.h> 20#include <sound/core.h>
20#include <sound/pcm.h> 21#include <sound/pcm.h>
21#include <sound/pcm_params.h> 22#include <sound/pcm_params.h>
@@ -140,6 +141,7 @@ struct pm860x_priv {
140 unsigned int filter; 141 unsigned int filter;
141 struct snd_soc_codec *codec; 142 struct snd_soc_codec *codec;
142 struct i2c_client *i2c; 143 struct i2c_client *i2c;
144 struct regmap *regmap;
143 struct pm860x_chip *chip; 145 struct pm860x_chip *chip;
144 struct pm860x_det det; 146 struct pm860x_det det;
145 147
@@ -269,48 +271,6 @@ static struct st_gain st_table[] = {
269 { -86, 29, 0}, { -56, 30, 0}, { -28, 31, 0}, { 0, 0, 0}, 271 { -86, 29, 0}, { -56, 30, 0}, { -28, 31, 0}, { 0, 0, 0},
270}; 272};
271 273
272static int pm860x_volatile(unsigned int reg)
273{
274 BUG_ON(reg >= REG_CACHE_SIZE);
275
276 switch (reg) {
277 case PM860X_AUDIO_SUPPLIES_2:
278 return 1;
279 }
280
281 return 0;
282}
283
284static unsigned int pm860x_read_reg_cache(struct snd_soc_codec *codec,
285 unsigned int reg)
286{
287 unsigned char *cache = codec->reg_cache;
288
289 BUG_ON(reg >= REG_CACHE_SIZE);
290
291 if (pm860x_volatile(reg))
292 return cache[reg];
293
294 reg += REG_CACHE_BASE;
295
296 return pm860x_reg_read(codec->control_data, reg);
297}
298
299static int pm860x_write_reg_cache(struct snd_soc_codec *codec,
300 unsigned int reg, unsigned int value)
301{
302 unsigned char *cache = codec->reg_cache;
303
304 BUG_ON(reg >= REG_CACHE_SIZE);
305
306 if (!pm860x_volatile(reg))
307 cache[reg] = (unsigned char)value;
308
309 reg += REG_CACHE_BASE;
310
311 return pm860x_reg_write(codec->control_data, reg, value);
312}
313
314static int snd_soc_get_volsw_2r_st(struct snd_kcontrol *kcontrol, 274static int snd_soc_get_volsw_2r_st(struct snd_kcontrol *kcontrol,
315 struct snd_ctl_elem_value *ucontrol) 275 struct snd_ctl_elem_value *ucontrol)
316{ 276{
@@ -1169,6 +1129,7 @@ static int pm860x_i2s_set_dai_fmt(struct snd_soc_dai *codec_dai,
1169static int pm860x_set_bias_level(struct snd_soc_codec *codec, 1129static int pm860x_set_bias_level(struct snd_soc_codec *codec,
1170 enum snd_soc_bias_level level) 1130 enum snd_soc_bias_level level)
1171{ 1131{
1132 struct pm860x_priv *pm860x = snd_soc_codec_get_drvdata(codec);
1172 int data; 1133 int data;
1173 1134
1174 switch (level) { 1135 switch (level) {
@@ -1182,17 +1143,17 @@ static int pm860x_set_bias_level(struct snd_soc_codec *codec,
1182 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { 1143 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
1183 /* Enable Audio PLL & Audio section */ 1144 /* Enable Audio PLL & Audio section */
1184 data = AUDIO_PLL | AUDIO_SECTION_ON; 1145 data = AUDIO_PLL | AUDIO_SECTION_ON;
1185 pm860x_reg_write(codec->control_data, REG_MISC2, data); 1146 pm860x_reg_write(pm860x->i2c, REG_MISC2, data);
1186 udelay(300); 1147 udelay(300);
1187 data = AUDIO_PLL | AUDIO_SECTION_RESET 1148 data = AUDIO_PLL | AUDIO_SECTION_RESET
1188 | AUDIO_SECTION_ON; 1149 | AUDIO_SECTION_ON;
1189 pm860x_reg_write(codec->control_data, REG_MISC2, data); 1150 pm860x_reg_write(pm860x->i2c, REG_MISC2, data);
1190 } 1151 }
1191 break; 1152 break;
1192 1153
1193 case SND_SOC_BIAS_OFF: 1154 case SND_SOC_BIAS_OFF:
1194 data = AUDIO_PLL | AUDIO_SECTION_RESET | AUDIO_SECTION_ON; 1155 data = AUDIO_PLL | AUDIO_SECTION_RESET | AUDIO_SECTION_ON;
1195 pm860x_set_bits(codec->control_data, REG_MISC2, data, 0); 1156 pm860x_set_bits(pm860x->i2c, REG_MISC2, data, 0);
1196 break; 1157 break;
1197 } 1158 }
1198 codec->dapm.bias_level = level; 1159 codec->dapm.bias_level = level;
@@ -1322,17 +1283,17 @@ int pm860x_hs_jack_detect(struct snd_soc_codec *codec,
1322 pm860x->det.lo_shrt = lo_shrt; 1283 pm860x->det.lo_shrt = lo_shrt;
1323 1284
1324 if (det & SND_JACK_HEADPHONE) 1285 if (det & SND_JACK_HEADPHONE)
1325 pm860x_set_bits(codec->control_data, REG_HS_DET, 1286 pm860x_set_bits(pm860x->i2c, REG_HS_DET,
1326 EN_HS_DET, EN_HS_DET); 1287 EN_HS_DET, EN_HS_DET);
1327 /* headset short detect */ 1288 /* headset short detect */
1328 if (hs_shrt) { 1289 if (hs_shrt) {
1329 data = CLR_SHORT_HS2 | CLR_SHORT_HS1; 1290 data = CLR_SHORT_HS2 | CLR_SHORT_HS1;
1330 pm860x_set_bits(codec->control_data, REG_SHORTS, data, data); 1291 pm860x_set_bits(pm860x->i2c, REG_SHORTS, data, data);
1331 } 1292 }
1332 /* Lineout short detect */ 1293 /* Lineout short detect */
1333 if (lo_shrt) { 1294 if (lo_shrt) {
1334 data = CLR_SHORT_LO2 | CLR_SHORT_LO1; 1295 data = CLR_SHORT_LO2 | CLR_SHORT_LO1;
1335 pm860x_set_bits(codec->control_data, REG_SHORTS, data, data); 1296 pm860x_set_bits(pm860x->i2c, REG_SHORTS, data, data);
1336 } 1297 }
1337 1298
1338 /* sync status */ 1299 /* sync status */
@@ -1350,7 +1311,7 @@ int pm860x_mic_jack_detect(struct snd_soc_codec *codec,
1350 pm860x->det.mic_det = det; 1311 pm860x->det.mic_det = det;
1351 1312
1352 if (det & SND_JACK_MICROPHONE) 1313 if (det & SND_JACK_MICROPHONE)
1353 pm860x_set_bits(codec->control_data, REG_MIC_DET, 1314 pm860x_set_bits(pm860x->i2c, REG_MIC_DET,
1354 MICDET_MASK, MICDET_MASK); 1315 MICDET_MASK, MICDET_MASK);
1355 1316
1356 /* sync status */ 1317 /* sync status */
@@ -1366,7 +1327,7 @@ static int pm860x_probe(struct snd_soc_codec *codec)
1366 1327
1367 pm860x->codec = codec; 1328 pm860x->codec = codec;
1368 1329
1369 codec->control_data = pm860x->i2c; 1330 codec->control_data = pm860x->regmap;
1370 1331
1371 for (i = 0; i < 4; i++) { 1332 for (i = 0; i < 4; i++) {
1372 ret = request_threaded_irq(pm860x->irq[i], NULL, 1333 ret = request_threaded_irq(pm860x->irq[i], NULL,
@@ -1380,14 +1341,6 @@ static int pm860x_probe(struct snd_soc_codec *codec)
1380 1341
1381 pm860x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1342 pm860x_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1382 1343
1383 ret = pm860x_bulk_read(codec->control_data, REG_CACHE_BASE,
1384 REG_CACHE_SIZE, codec->reg_cache);
1385 if (ret < 0) {
1386 dev_err(codec->dev, "Failed to fill register cache: %d\n",
1387 ret);
1388 goto out;
1389 }
1390
1391 return 0; 1344 return 0;
1392 1345
1393out: 1346out:
@@ -1410,10 +1363,6 @@ static int pm860x_remove(struct snd_soc_codec *codec)
1410static struct snd_soc_codec_driver soc_codec_dev_pm860x = { 1363static struct snd_soc_codec_driver soc_codec_dev_pm860x = {
1411 .probe = pm860x_probe, 1364 .probe = pm860x_probe,
1412 .remove = pm860x_remove, 1365 .remove = pm860x_remove,
1413 .read = pm860x_read_reg_cache,
1414 .write = pm860x_write_reg_cache,
1415 .reg_cache_size = REG_CACHE_SIZE,
1416 .reg_word_size = sizeof(u8),
1417 .set_bias_level = pm860x_set_bias_level, 1366 .set_bias_level = pm860x_set_bias_level,
1418 1367
1419 .controls = pm860x_snd_controls, 1368 .controls = pm860x_snd_controls,
@@ -1439,6 +1388,8 @@ static int pm860x_codec_probe(struct platform_device *pdev)
1439 pm860x->chip = chip; 1388 pm860x->chip = chip;
1440 pm860x->i2c = (chip->id == CHIP_PM8607) ? chip->client 1389 pm860x->i2c = (chip->id == CHIP_PM8607) ? chip->client
1441 : chip->companion; 1390 : chip->companion;
1391 pm860x->regmap = (chip->id == CHIP_PM8607) ? chip->regmap
1392 : chip->regmap_companion;
1442 platform_set_drvdata(pdev, pm860x); 1393 platform_set_drvdata(pdev, pm860x);
1443 1394
1444 for (i = 0; i < 4; i++) { 1395 for (i = 0; i < 4; i++) {
diff --git a/sound/soc/codecs/88pm860x-codec.h b/sound/soc/codecs/88pm860x-codec.h
index 3364ba4a3607..f7282f4f4a79 100644
--- a/sound/soc/codecs/88pm860x-codec.h
+++ b/sound/soc/codecs/88pm860x-codec.h
@@ -12,67 +12,66 @@
12#ifndef __88PM860X_H 12#ifndef __88PM860X_H
13#define __88PM860X_H 13#define __88PM860X_H
14 14
15/* The offset of these registers are 0xb0 */ 15#define PM860X_PCM_IFACE_1 0xb0
16#define PM860X_PCM_IFACE_1 0x00 16#define PM860X_PCM_IFACE_2 0xb1
17#define PM860X_PCM_IFACE_2 0x01 17#define PM860X_PCM_IFACE_3 0xb2
18#define PM860X_PCM_IFACE_3 0x02 18#define PM860X_PCM_RATE 0xb3
19#define PM860X_PCM_RATE 0x03 19#define PM860X_EC_PATH 0xb4
20#define PM860X_EC_PATH 0x04 20#define PM860X_SIDETONE_L_GAIN 0xb5
21#define PM860X_SIDETONE_L_GAIN 0x05 21#define PM860X_SIDETONE_R_GAIN 0xb6
22#define PM860X_SIDETONE_R_GAIN 0x06 22#define PM860X_SIDETONE_SHIFT 0xb7
23#define PM860X_SIDETONE_SHIFT 0x07 23#define PM860X_ADC_OFFSET_1 0xb8
24#define PM860X_ADC_OFFSET_1 0x08 24#define PM860X_ADC_OFFSET_2 0xb9
25#define PM860X_ADC_OFFSET_2 0x09 25#define PM860X_DMIC_DELAY 0xba
26#define PM860X_DMIC_DELAY 0x0a
27 26
28#define PM860X_I2S_IFACE_1 0x0b 27#define PM860X_I2S_IFACE_1 0xbb
29#define PM860X_I2S_IFACE_2 0x0c 28#define PM860X_I2S_IFACE_2 0xbc
30#define PM860X_I2S_IFACE_3 0x0d 29#define PM860X_I2S_IFACE_3 0xbd
31#define PM860X_I2S_IFACE_4 0x0e 30#define PM860X_I2S_IFACE_4 0xbe
32#define PM860X_EQUALIZER_N0_1 0x0f 31#define PM860X_EQUALIZER_N0_1 0xbf
33#define PM860X_EQUALIZER_N0_2 0x10 32#define PM860X_EQUALIZER_N0_2 0xc0
34#define PM860X_EQUALIZER_N1_1 0x11 33#define PM860X_EQUALIZER_N1_1 0xc1
35#define PM860X_EQUALIZER_N1_2 0x12 34#define PM860X_EQUALIZER_N1_2 0xc2
36#define PM860X_EQUALIZER_D1_1 0x13 35#define PM860X_EQUALIZER_D1_1 0xc3
37#define PM860X_EQUALIZER_D1_2 0x14 36#define PM860X_EQUALIZER_D1_2 0xc4
38#define PM860X_LOFI_GAIN_LEFT 0x15 37#define PM860X_LOFI_GAIN_LEFT 0xc5
39#define PM860X_LOFI_GAIN_RIGHT 0x16 38#define PM860X_LOFI_GAIN_RIGHT 0xc6
40#define PM860X_HIFIL_GAIN_LEFT 0x17 39#define PM860X_HIFIL_GAIN_LEFT 0xc7
41#define PM860X_HIFIL_GAIN_RIGHT 0x18 40#define PM860X_HIFIL_GAIN_RIGHT 0xc8
42#define PM860X_HIFIR_GAIN_LEFT 0x19 41#define PM860X_HIFIR_GAIN_LEFT 0xc9
43#define PM860X_HIFIR_GAIN_RIGHT 0x1a 42#define PM860X_HIFIR_GAIN_RIGHT 0xca
44#define PM860X_DAC_OFFSET 0x1b 43#define PM860X_DAC_OFFSET 0xcb
45#define PM860X_OFFSET_LEFT_1 0x1c 44#define PM860X_OFFSET_LEFT_1 0xcc
46#define PM860X_OFFSET_LEFT_2 0x1d 45#define PM860X_OFFSET_LEFT_2 0xcd
47#define PM860X_OFFSET_RIGHT_1 0x1e 46#define PM860X_OFFSET_RIGHT_1 0xce
48#define PM860X_OFFSET_RIGHT_2 0x1f 47#define PM860X_OFFSET_RIGHT_2 0xcf
49#define PM860X_ADC_ANA_1 0x20 48#define PM860X_ADC_ANA_1 0xd0
50#define PM860X_ADC_ANA_2 0x21 49#define PM860X_ADC_ANA_2 0xd1
51#define PM860X_ADC_ANA_3 0x22 50#define PM860X_ADC_ANA_3 0xd2
52#define PM860X_ADC_ANA_4 0x23 51#define PM860X_ADC_ANA_4 0xd3
53#define PM860X_ANA_TO_ANA 0x24 52#define PM860X_ANA_TO_ANA 0xd4
54#define PM860X_HS1_CTRL 0x25 53#define PM860X_HS1_CTRL 0xd5
55#define PM860X_HS2_CTRL 0x26 54#define PM860X_HS2_CTRL 0xd6
56#define PM860X_LO1_CTRL 0x27 55#define PM860X_LO1_CTRL 0xd7
57#define PM860X_LO2_CTRL 0x28 56#define PM860X_LO2_CTRL 0xd8
58#define PM860X_EAR_CTRL_1 0x29 57#define PM860X_EAR_CTRL_1 0xd9
59#define PM860X_EAR_CTRL_2 0x2a 58#define PM860X_EAR_CTRL_2 0xda
60#define PM860X_AUDIO_SUPPLIES_1 0x2b 59#define PM860X_AUDIO_SUPPLIES_1 0xdb
61#define PM860X_AUDIO_SUPPLIES_2 0x2c 60#define PM860X_AUDIO_SUPPLIES_2 0xdc
62#define PM860X_ADC_EN_1 0x2d 61#define PM860X_ADC_EN_1 0xdd
63#define PM860X_ADC_EN_2 0x2e 62#define PM860X_ADC_EN_2 0xde
64#define PM860X_DAC_EN_1 0x2f 63#define PM860X_DAC_EN_1 0xdf
65#define PM860X_DAC_EN_2 0x31 64#define PM860X_DAC_EN_2 0xe1
66#define PM860X_AUDIO_CAL_1 0x32 65#define PM860X_AUDIO_CAL_1 0xe2
67#define PM860X_AUDIO_CAL_2 0x33 66#define PM860X_AUDIO_CAL_2 0xe3
68#define PM860X_AUDIO_CAL_3 0x34 67#define PM860X_AUDIO_CAL_3 0xe4
69#define PM860X_AUDIO_CAL_4 0x35 68#define PM860X_AUDIO_CAL_4 0xe5
70#define PM860X_AUDIO_CAL_5 0x36 69#define PM860X_AUDIO_CAL_5 0xe6
71#define PM860X_ANA_INPUT_SEL_1 0x37 70#define PM860X_ANA_INPUT_SEL_1 0xe7
72#define PM860X_ANA_INPUT_SEL_2 0x38 71#define PM860X_ANA_INPUT_SEL_2 0xe8
73 72
74#define PM860X_PCM_IFACE_4 0x39 73#define PM860X_PCM_IFACE_4 0xe9
75#define PM860X_I2S_IFACE_5 0x3a 74#define PM860X_I2S_IFACE_5 0xea
76 75
77#define PM860X_SHORTS 0x3b 76#define PM860X_SHORTS 0x3b
78#define PM860X_PLL_ADJ_1 0x3c 77#define PM860X_PLL_ADJ_1 0x3c