diff options
author | Clemens Ladisch <clemens@ladisch.de> | 2009-09-28 05:18:45 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-09-28 05:54:29 -0400 |
commit | 6f0de3ce068e48b033b5e4d0822b47218e9d206c (patch) | |
tree | 6e4e9c054a867e5deee94df181701dedc99e4275 /sound/pci/oxygen/hifier.c | |
parent | dc0adf48daa81b05765d3c5ebab76321f77e9d21 (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.c | 46 |
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 = { | |||
57 | MODULE_DEVICE_TABLE(pci, hifier_ids); | 57 | MODULE_DEVICE_TABLE(pci, hifier_ids); |
58 | 58 | ||
59 | struct hifier_data { | 59 | struct hifier_data { |
60 | u8 ak4396_ctl2; | 60 | u8 ak4396_regs[5]; |
61 | }; | 61 | }; |
62 | 62 | ||
63 | static void ak4396_write(struct oxygen *chip, u8 reg, u8 value) | 63 | static 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 | ||
73 | static void update_ak4396_volume(struct oxygen *chip) | 76 | static 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 | ||
79 | static void hifier_registers_init(struct oxygen *chip) | 84 | static 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 | ||
89 | static void hifier_init(struct oxygen *chip) | 96 | static 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 | |||
142 | static 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 | ||
131 | static void update_ak4396_mute(struct oxygen *chip) | 148 | static 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 | ||
143 | static void set_cs5340_params(struct oxygen *chip, | 159 | static void set_cs5340_params(struct oxygen *chip, |