aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/oxygen/hifier.c
diff options
context:
space:
mode:
authorClemens Ladisch <clemens@ladisch.de>2009-09-28 05:18:45 -0400
committerTakashi Iwai <tiwai@suse.de>2009-09-28 05:54:29 -0400
commit6f0de3ce068e48b033b5e4d0822b47218e9d206c (patch)
tree6e4e9c054a867e5deee94df181701dedc99e4275 /sound/pci/oxygen/hifier.c
parentdc0adf48daa81b05765d3c5ebab76321f77e9d21 (diff)
sound: oxygen: cache codec registers
Keep a cache of codec registers to avoid unnecessary writes. Signed-off-by: Clemens Ladisch <clemens@ladisch.de> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/oxygen/hifier.c')
-rw-r--r--sound/pci/oxygen/hifier.c46
1 files changed, 31 insertions, 15 deletions
diff --git a/sound/pci/oxygen/hifier.c b/sound/pci/oxygen/hifier.c
index 19e9e0123304..2079c100aabc 100644
--- a/sound/pci/oxygen/hifier.c
+++ b/sound/pci/oxygen/hifier.c
@@ -57,23 +57,28 @@ static struct pci_device_id hifier_ids[] __devinitdata = {
57MODULE_DEVICE_TABLE(pci, hifier_ids); 57MODULE_DEVICE_TABLE(pci, hifier_ids);
58 58
59struct hifier_data { 59struct hifier_data {
60 u8 ak4396_ctl2; 60 u8 ak4396_regs[5];
61}; 61};
62 62
63static void ak4396_write(struct oxygen *chip, u8 reg, u8 value) 63static void ak4396_write(struct oxygen *chip, u8 reg, u8 value)
64{ 64{
65 struct hifier_data *data = chip->model_data;
66
65 oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER | 67 oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
66 OXYGEN_SPI_DATA_LENGTH_2 | 68 OXYGEN_SPI_DATA_LENGTH_2 |
67 OXYGEN_SPI_CLOCK_160 | 69 OXYGEN_SPI_CLOCK_160 |
68 (0 << OXYGEN_SPI_CODEC_SHIFT) | 70 (0 << OXYGEN_SPI_CODEC_SHIFT) |
69 OXYGEN_SPI_CEN_LATCH_CLOCK_HI, 71 OXYGEN_SPI_CEN_LATCH_CLOCK_HI,
70 AK4396_WRITE | (reg << 8) | value); 72 AK4396_WRITE | (reg << 8) | value);
73 data->ak4396_regs[reg] = value;
71} 74}
72 75
73static void update_ak4396_volume(struct oxygen *chip) 76static void ak4396_write_cached(struct oxygen *chip, u8 reg, u8 value)
74{ 77{
75 ak4396_write(chip, AK4396_LCH_ATT, chip->dac_volume[0]); 78 struct hifier_data *data = chip->model_data;
76 ak4396_write(chip, AK4396_RCH_ATT, chip->dac_volume[1]); 79
80 if (value != data->ak4396_regs[reg])
81 ak4396_write(chip, reg, value);
77} 82}
78 83
79static void hifier_registers_init(struct oxygen *chip) 84static void hifier_registers_init(struct oxygen *chip)
@@ -81,16 +86,19 @@ static void hifier_registers_init(struct oxygen *chip)
81 struct hifier_data *data = chip->model_data; 86 struct hifier_data *data = chip->model_data;
82 87
83 ak4396_write(chip, AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN); 88 ak4396_write(chip, AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN);
84 ak4396_write(chip, AK4396_CONTROL_2, data->ak4396_ctl2); 89 ak4396_write(chip, AK4396_CONTROL_2,
90 data->ak4396_regs[AK4396_CONTROL_2]);
85 ak4396_write(chip, AK4396_CONTROL_3, AK4396_PCM); 91 ak4396_write(chip, AK4396_CONTROL_3, AK4396_PCM);
86 update_ak4396_volume(chip); 92 ak4396_write(chip, AK4396_LCH_ATT, chip->dac_volume[0]);
93 ak4396_write(chip, AK4396_RCH_ATT, chip->dac_volume[1]);
87} 94}
88 95
89static void hifier_init(struct oxygen *chip) 96static void hifier_init(struct oxygen *chip)
90{ 97{
91 struct hifier_data *data = chip->model_data; 98 struct hifier_data *data = chip->model_data;
92 99
93 data->ak4396_ctl2 = AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL; 100 data->ak4396_regs[AK4396_CONTROL_2] =
101 AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL;
94 hifier_registers_init(chip); 102 hifier_registers_init(chip);
95 103
96 snd_component_add(chip->card, "AK4396"); 104 snd_component_add(chip->card, "AK4396");
@@ -112,20 +120,29 @@ static void set_ak4396_params(struct oxygen *chip,
112 struct hifier_data *data = chip->model_data; 120 struct hifier_data *data = chip->model_data;
113 u8 value; 121 u8 value;
114 122
115 value = data->ak4396_ctl2 & ~AK4396_DFS_MASK; 123 value = data->ak4396_regs[AK4396_CONTROL_2] & ~AK4396_DFS_MASK;
116 if (params_rate(params) <= 54000) 124 if (params_rate(params) <= 54000)
117 value |= AK4396_DFS_NORMAL; 125 value |= AK4396_DFS_NORMAL;
118 else if (params_rate(params) <= 108000) 126 else if (params_rate(params) <= 108000)
119 value |= AK4396_DFS_DOUBLE; 127 value |= AK4396_DFS_DOUBLE;
120 else 128 else
121 value |= AK4396_DFS_QUAD; 129 value |= AK4396_DFS_QUAD;
122 data->ak4396_ctl2 = value;
123 130
124 msleep(1); /* wait for the new MCLK to become stable */ 131 msleep(1); /* wait for the new MCLK to become stable */
125 132
126 ak4396_write(chip, AK4396_CONTROL_1, AK4396_DIF_24_MSB); 133 if (value != data->ak4396_regs[AK4396_CONTROL_2]) {
127 ak4396_write(chip, AK4396_CONTROL_2, value); 134 ak4396_write(chip, AK4396_CONTROL_1,
128 ak4396_write(chip, AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN); 135 AK4396_DIF_24_MSB);
136 ak4396_write(chip, AK4396_CONTROL_2, value);
137 ak4396_write(chip, AK4396_CONTROL_1,
138 AK4396_DIF_24_MSB | AK4396_RSTN);
139 }
140}
141
142static void update_ak4396_volume(struct oxygen *chip)
143{
144 ak4396_write_cached(chip, AK4396_LCH_ATT, chip->dac_volume[0]);
145 ak4396_write_cached(chip, AK4396_RCH_ATT, chip->dac_volume[1]);
129} 146}
130 147
131static void update_ak4396_mute(struct oxygen *chip) 148static void update_ak4396_mute(struct oxygen *chip)
@@ -133,11 +150,10 @@ static void update_ak4396_mute(struct oxygen *chip)
133 struct hifier_data *data = chip->model_data; 150 struct hifier_data *data = chip->model_data;
134 u8 value; 151 u8 value;
135 152
136 value = data->ak4396_ctl2 & ~AK4396_SMUTE; 153 value = data->ak4396_regs[AK4396_CONTROL_2] & ~AK4396_SMUTE;
137 if (chip->dac_mute) 154 if (chip->dac_mute)
138 value |= AK4396_SMUTE; 155 value |= AK4396_SMUTE;
139 data->ak4396_ctl2 = value; 156 ak4396_write_cached(chip, AK4396_CONTROL_2, value);
140 ak4396_write(chip, AK4396_CONTROL_2, value);
141} 157}
142 158
143static void set_cs5340_params(struct oxygen *chip, 159static void set_cs5340_params(struct oxygen *chip,