Skip to content

Commit f9dfbf9

Browse files
AxelLinbroonie
authored andcommitted
ASoC: tlv320aic23: convert to soc-cache
Signed-off-by: Axel Lin <[email protected]> Signed-off-by: Mark Brown <[email protected]>
1 parent a6f096f commit f9dfbf9

File tree

1 file changed

+52
-115
lines changed

1 file changed

+52
-115
lines changed

sound/soc/codecs/tlv320aic23.c

Lines changed: 52 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -47,63 +47,6 @@ static const u16 tlv320aic23_reg[] = {
4747
0x0000, 0x0000, 0x0000, 0x0000, /* 12 */
4848
};
4949

50-
/*
51-
* read tlv320aic23 register cache
52-
*/
53-
static inline unsigned int tlv320aic23_read_reg_cache(struct snd_soc_codec
54-
*codec, unsigned int reg)
55-
{
56-
u16 *cache = codec->reg_cache;
57-
if (reg >= ARRAY_SIZE(tlv320aic23_reg))
58-
return -1;
59-
return cache[reg];
60-
}
61-
62-
/*
63-
* write tlv320aic23 register cache
64-
*/
65-
static inline void tlv320aic23_write_reg_cache(struct snd_soc_codec *codec,
66-
u8 reg, u16 value)
67-
{
68-
u16 *cache = codec->reg_cache;
69-
if (reg >= ARRAY_SIZE(tlv320aic23_reg))
70-
return;
71-
cache[reg] = value;
72-
}
73-
74-
/*
75-
* write to the tlv320aic23 register space
76-
*/
77-
static int tlv320aic23_write(struct snd_soc_codec *codec, unsigned int reg,
78-
unsigned int value)
79-
{
80-
81-
u8 data[2];
82-
83-
/* TLV320AIC23 has 7 bit address and 9 bits of data
84-
* so we need to switch one data bit into reg and rest
85-
* of data into val
86-
*/
87-
88-
if (reg > 9 && reg != 15) {
89-
printk(KERN_WARNING "%s Invalid register R%u\n", __func__, reg);
90-
return -1;
91-
}
92-
93-
data[0] = (reg << 1) | (value >> 8 & 0x01);
94-
data[1] = value & 0xff;
95-
96-
tlv320aic23_write_reg_cache(codec, reg, value);
97-
98-
if (codec->hw_write(codec->control_data, data, 2) == 2)
99-
return 0;
100-
101-
printk(KERN_ERR "%s cannot write %03x to register R%u\n", __func__,
102-
value, reg);
103-
104-
return -EIO;
105-
}
106-
10750
static const char *rec_src_text[] = { "Line", "Mic" };
10851
static const char *deemph_text[] = {"None", "32Khz", "44.1Khz", "48Khz"};
10952

@@ -139,8 +82,8 @@ static int snd_soc_tlv320aic23_put_volsw(struct snd_kcontrol *kcontrol,
13982
*/
14083
val = (val >= 4) ? 4 : (3 - val);
14184

142-
reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_ANLG) & (~0x1C0);
143-
tlv320aic23_write(codec, TLV320AIC23_ANLG, reg | (val << 6));
85+
reg = snd_soc_read(codec, TLV320AIC23_ANLG) & (~0x1C0);
86+
snd_soc_write(codec, TLV320AIC23_ANLG, reg | (val << 6));
14487

14588
return 0;
14689
}
@@ -151,7 +94,7 @@ static int snd_soc_tlv320aic23_get_volsw(struct snd_kcontrol *kcontrol,
15194
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
15295
u16 val;
15396

154-
val = tlv320aic23_read_reg_cache(codec, TLV320AIC23_ANLG) & (0x1C0);
97+
val = snd_soc_read(codec, TLV320AIC23_ANLG) & (0x1C0);
15598
val = val >> 6;
15699
val = (val >= 4) ? 4 : (3 - val);
157100
ucontrol->value.integer.value[0] = val;
@@ -232,7 +175,6 @@ static const struct snd_soc_dapm_route tlv320aic23_intercon[] = {
232175
/* AIC23 driver data */
233176
struct aic23 {
234177
enum snd_soc_control_type control_type;
235-
void *control_data;
236178
int mclk;
237179
int requested_adc;
238180
int requested_dac;
@@ -344,7 +286,7 @@ static int find_rate(int mclk, u32 need_adc, u32 need_dac)
344286
static void get_current_sample_rates(struct snd_soc_codec *codec, int mclk,
345287
u32 *sample_rate_adc, u32 *sample_rate_dac)
346288
{
347-
int src = tlv320aic23_read_reg_cache(codec, TLV320AIC23_SRATE);
289+
int src = snd_soc_read(codec, TLV320AIC23_SRATE);
348290
int sr = (src >> 2) & 0x0f;
349291
int val = (mclk / bosr_usb_divisor_table[src & 3]);
350292
int adc = (val * sr_adc_mult_table[sr]) / SR_MULT;
@@ -368,7 +310,7 @@ static int set_sample_rate_control(struct snd_soc_codec *codec, int mclk,
368310
__func__, sample_rate_adc, sample_rate_dac);
369311
return -EINVAL;
370312
}
371-
tlv320aic23_write(codec, TLV320AIC23_SRATE, data);
313+
snd_soc_write(codec, TLV320AIC23_SRATE, data);
372314
#ifdef DEBUG
373315
{
374316
u32 adc, dac;
@@ -407,9 +349,8 @@ static int tlv320aic23_hw_params(struct snd_pcm_substream *substream,
407349
if (ret < 0)
408350
return ret;
409351

410-
iface_reg =
411-
tlv320aic23_read_reg_cache(codec,
412-
TLV320AIC23_DIGT_FMT) & ~(0x03 << 2);
352+
iface_reg = snd_soc_read(codec, TLV320AIC23_DIGT_FMT) & ~(0x03 << 2);
353+
413354
switch (params_format(params)) {
414355
case SNDRV_PCM_FORMAT_S16_LE:
415356
break;
@@ -423,7 +364,7 @@ static int tlv320aic23_hw_params(struct snd_pcm_substream *substream,
423364
iface_reg |= (0x03 << 2);
424365
break;
425366
}
426-
tlv320aic23_write(codec, TLV320AIC23_DIGT_FMT, iface_reg);
367+
snd_soc_write(codec, TLV320AIC23_DIGT_FMT, iface_reg);
427368

428369
return 0;
429370
}
@@ -435,7 +376,7 @@ static int tlv320aic23_pcm_prepare(struct snd_pcm_substream *substream,
435376
struct snd_soc_codec *codec = rtd->codec;
436377

437378
/* set active */
438-
tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0001);
379+
snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x0001);
439380

440381
return 0;
441382
}
@@ -450,7 +391,7 @@ static void tlv320aic23_shutdown(struct snd_pcm_substream *substream,
450391
/* deactivate */
451392
if (!codec->active) {
452393
udelay(50);
453-
tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0);
394+
snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x0);
454395
}
455396
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
456397
aic23->requested_dac = 0;
@@ -463,14 +404,14 @@ static int tlv320aic23_mute(struct snd_soc_dai *dai, int mute)
463404
struct snd_soc_codec *codec = dai->codec;
464405
u16 reg;
465406

466-
reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_DIGT);
407+
reg = snd_soc_read(codec, TLV320AIC23_DIGT);
467408
if (mute)
468409
reg |= TLV320AIC23_DACM_MUTE;
469410

470411
else
471412
reg &= ~TLV320AIC23_DACM_MUTE;
472413

473-
tlv320aic23_write(codec, TLV320AIC23_DIGT, reg);
414+
snd_soc_write(codec, TLV320AIC23_DIGT, reg);
474415

475416
return 0;
476417
}
@@ -481,8 +422,7 @@ static int tlv320aic23_set_dai_fmt(struct snd_soc_dai *codec_dai,
481422
struct snd_soc_codec *codec = codec_dai->codec;
482423
u16 iface_reg;
483424

484-
iface_reg =
485-
tlv320aic23_read_reg_cache(codec, TLV320AIC23_DIGT_FMT) & (~0x03);
425+
iface_reg = snd_soc_read(codec, TLV320AIC23_DIGT_FMT) & (~0x03);
486426

487427
/* set master/slave audio interface */
488428
switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
@@ -516,7 +456,7 @@ static int tlv320aic23_set_dai_fmt(struct snd_soc_dai *codec_dai,
516456

517457
}
518458

519-
tlv320aic23_write(codec, TLV320AIC23_DIGT_FMT, iface_reg);
459+
snd_soc_write(codec, TLV320AIC23_DIGT_FMT, iface_reg);
520460

521461
return 0;
522462
}
@@ -532,26 +472,26 @@ static int tlv320aic23_set_dai_sysclk(struct snd_soc_dai *codec_dai,
532472
static int tlv320aic23_set_bias_level(struct snd_soc_codec *codec,
533473
enum snd_soc_bias_level level)
534474
{
535-
u16 reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_PWR) & 0xff7f;
475+
u16 reg = snd_soc_read(codec, TLV320AIC23_PWR) & 0xff7f;
536476

537477
switch (level) {
538478
case SND_SOC_BIAS_ON:
539479
/* vref/mid, osc on, dac unmute */
540480
reg &= ~(TLV320AIC23_DEVICE_PWR_OFF | TLV320AIC23_OSC_OFF | \
541481
TLV320AIC23_DAC_OFF);
542-
tlv320aic23_write(codec, TLV320AIC23_PWR, reg);
482+
snd_soc_write(codec, TLV320AIC23_PWR, reg);
543483
break;
544484
case SND_SOC_BIAS_PREPARE:
545485
break;
546486
case SND_SOC_BIAS_STANDBY:
547487
/* everything off except vref/vmid, */
548-
tlv320aic23_write(codec, TLV320AIC23_PWR, reg | \
549-
TLV320AIC23_CLK_OFF);
488+
snd_soc_write(codec, TLV320AIC23_PWR,
489+
reg | TLV320AIC23_CLK_OFF);
550490
break;
551491
case SND_SOC_BIAS_OFF:
552492
/* everything off, dac mute, inactive */
553-
tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x0);
554-
tlv320aic23_write(codec, TLV320AIC23_PWR, 0xffff);
493+
snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x0);
494+
snd_soc_write(codec, TLV320AIC23_PWR, 0xffff);
555495
break;
556496
}
557497
codec->dapm.bias_level = level;
@@ -598,13 +538,7 @@ static int tlv320aic23_suspend(struct snd_soc_codec *codec,
598538

599539
static int tlv320aic23_resume(struct snd_soc_codec *codec)
600540
{
601-
u16 reg;
602-
603-
/* Sync reg_cache with the hardware */
604-
for (reg = 0; reg <= TLV320AIC23_ACTIVE; reg++) {
605-
u16 val = tlv320aic23_read_reg_cache(codec, reg);
606-
tlv320aic23_write(codec, reg, val);
607-
}
541+
snd_soc_cache_sync(codec);
608542
tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
609543

610544
return 0;
@@ -613,46 +547,52 @@ static int tlv320aic23_resume(struct snd_soc_codec *codec)
613547
static int tlv320aic23_probe(struct snd_soc_codec *codec)
614548
{
615549
struct aic23 *aic23 = snd_soc_codec_get_drvdata(codec);
616-
int reg;
550+
int ret;
617551

618552
printk(KERN_INFO "AIC23 Audio Codec %s\n", AIC23_VERSION);
619-
codec->control_data = aic23->control_data;
620-
codec->hw_write = (hw_write_t)i2c_master_send;
621-
codec->hw_read = NULL;
553+
554+
ret = snd_soc_codec_set_cache_io(codec, 7, 9, aic23->control_type);
555+
if (ret < 0) {
556+
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
557+
return ret;
558+
}
622559

623560
/* Reset codec */
624-
tlv320aic23_write(codec, TLV320AIC23_RESET, 0);
561+
snd_soc_write(codec, TLV320AIC23_RESET, 0);
562+
563+
/* Write the register default value to cache for reserved registers,
564+
* so the write to the these registers are suppressed by the cache
565+
* restore code when it skips writes of default registers.
566+
*/
567+
snd_soc_cache_write(codec, 0x0A, 0);
568+
snd_soc_cache_write(codec, 0x0B, 0);
569+
snd_soc_cache_write(codec, 0x0C, 0);
570+
snd_soc_cache_write(codec, 0x0D, 0);
571+
snd_soc_cache_write(codec, 0x0E, 0);
625572

626573
/* power on device */
627574
tlv320aic23_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
628575

629-
tlv320aic23_write(codec, TLV320AIC23_DIGT, TLV320AIC23_DEEMP_44K);
576+
snd_soc_write(codec, TLV320AIC23_DIGT, TLV320AIC23_DEEMP_44K);
630577

631578
/* Unmute input */
632-
reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_LINVOL);
633-
tlv320aic23_write(codec, TLV320AIC23_LINVOL,
634-
(reg & (~TLV320AIC23_LIM_MUTED)) |
635-
(TLV320AIC23_LRS_ENABLED));
579+
snd_soc_update_bits(codec, TLV320AIC23_LINVOL,
580+
TLV320AIC23_LIM_MUTED, TLV320AIC23_LRS_ENABLED);
636581

637-
reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_RINVOL);
638-
tlv320aic23_write(codec, TLV320AIC23_RINVOL,
639-
(reg & (~TLV320AIC23_LIM_MUTED)) |
640-
TLV320AIC23_LRS_ENABLED);
582+
snd_soc_update_bits(codec, TLV320AIC23_RINVOL,
583+
TLV320AIC23_LIM_MUTED, TLV320AIC23_LRS_ENABLED);
641584

642-
reg = tlv320aic23_read_reg_cache(codec, TLV320AIC23_ANLG);
643-
tlv320aic23_write(codec, TLV320AIC23_ANLG,
644-
(reg) & (~TLV320AIC23_BYPASS_ON) &
645-
(~TLV320AIC23_MICM_MUTED));
585+
snd_soc_update_bits(codec, TLV320AIC23_ANLG,
586+
TLV320AIC23_BYPASS_ON | TLV320AIC23_MICM_MUTED,
587+
0);
646588

647589
/* Default output volume */
648-
tlv320aic23_write(codec, TLV320AIC23_LCHNVOL,
649-
TLV320AIC23_DEFAULT_OUT_VOL &
650-
TLV320AIC23_OUT_VOL_MASK);
651-
tlv320aic23_write(codec, TLV320AIC23_RCHNVOL,
652-
TLV320AIC23_DEFAULT_OUT_VOL &
653-
TLV320AIC23_OUT_VOL_MASK);
590+
snd_soc_write(codec, TLV320AIC23_LCHNVOL,
591+
TLV320AIC23_DEFAULT_OUT_VOL & TLV320AIC23_OUT_VOL_MASK);
592+
snd_soc_write(codec, TLV320AIC23_RCHNVOL,
593+
TLV320AIC23_DEFAULT_OUT_VOL & TLV320AIC23_OUT_VOL_MASK);
654594

655-
tlv320aic23_write(codec, TLV320AIC23_ACTIVE, 0x1);
595+
snd_soc_write(codec, TLV320AIC23_ACTIVE, 0x1);
656596

657597
snd_soc_add_controls(codec, tlv320aic23_snd_controls,
658598
ARRAY_SIZE(tlv320aic23_snd_controls));
@@ -674,8 +614,6 @@ static struct snd_soc_codec_driver soc_codec_dev_tlv320aic23 = {
674614
.remove = tlv320aic23_remove,
675615
.suspend = tlv320aic23_suspend,
676616
.resume = tlv320aic23_resume,
677-
.read = tlv320aic23_read_reg_cache,
678-
.write = tlv320aic23_write,
679617
.set_bias_level = tlv320aic23_set_bias_level,
680618
.dapm_widgets = tlv320aic23_dapm_widgets,
681619
.num_dapm_widgets = ARRAY_SIZE(tlv320aic23_dapm_widgets),
@@ -702,7 +640,6 @@ static int tlv320aic23_codec_probe(struct i2c_client *i2c,
702640
return -ENOMEM;
703641

704642
i2c_set_clientdata(i2c, aic23);
705-
aic23->control_data = i2c;
706643
aic23->control_type = SND_SOC_I2C;
707644

708645
ret = snd_soc_register_codec(&i2c->dev,

0 commit comments

Comments
 (0)