diff options
-rw-r--r-- | sound/soc/codecs/88pm860x-codec.c | 75 | ||||
-rw-r--r-- | sound/soc/codecs/88pm860x-codec.h | 117 |
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 | ||
272 | static 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 | |||
284 | static 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 | |||
299 | static 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 | |||
314 | static int snd_soc_get_volsw_2r_st(struct snd_kcontrol *kcontrol, | 274 | static 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, | |||
1169 | static int pm860x_set_bias_level(struct snd_soc_codec *codec, | 1129 | static 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 | ||
1393 | out: | 1346 | out: |
@@ -1410,10 +1363,6 @@ static int pm860x_remove(struct snd_soc_codec *codec) | |||
1410 | static struct snd_soc_codec_driver soc_codec_dev_pm860x = { | 1363 | static 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 |