blob: 2f846f5e0f9fe1f3a60246cdcf8b960129bc7c46 [file] [log] [blame]
Hans Verkuilbd985162005-11-13 16:07:56 -08001/* cx25840 audio functions
2 *
3 * This program is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU General Public License
5 * as published by the Free Software Foundation; either version 2
6 * of the License, or (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 */
17
18
19#include <linux/videodev2.h>
20#include <linux/i2c.h>
Hans Verkuilbd985162005-11-13 16:07:56 -080021#include <media/v4l2-common.h>
Hans Verkuil31bc09b2006-03-25 10:26:09 -030022#include <media/cx25840.h>
Hans Verkuilbd985162005-11-13 16:07:56 -080023
Hans Verkuil31bc09b2006-03-25 10:26:09 -030024#include "cx25840-core.h"
Hans Verkuilbd985162005-11-13 16:07:56 -080025
Hans Verkuil3578d3d2006-01-09 15:25:41 -020026static int set_audclk_freq(struct i2c_client *client, u32 freq)
Hans Verkuilbd985162005-11-13 16:07:56 -080027{
Hans Verkuil9357b312008-11-29 12:50:06 -030028 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
Hans Verkuilbd985162005-11-13 16:07:56 -080029
Hans Verkuil3578d3d2006-01-09 15:25:41 -020030 if (freq != 32000 && freq != 44100 && freq != 48000)
31 return -EINVAL;
32
Hans Verkuilbd985162005-11-13 16:07:56 -080033 /* common for all inputs and rates */
34 /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x10 */
Sri Deevi149783b2009-03-03 06:07:42 -030035 if (!state->is_cx23885 && !state->is_cx231xx)
Steven Tothf2340812008-01-10 01:22:39 -030036 cx25840_write(client, 0x127, 0x50);
Hans Verkuilbd985162005-11-13 16:07:56 -080037
Hans Verkuila8bbf122006-01-09 15:25:42 -020038 if (state->aud_input != CX25840_AUDIO_SERIAL) {
Hans Verkuilbd985162005-11-13 16:07:56 -080039 switch (freq) {
Hans Verkuil3578d3d2006-01-09 15:25:41 -020040 case 32000:
Steven Tothf2340812008-01-10 01:22:39 -030041 if (state->is_cx23885) {
42 /* We don't have register values
43 * so avoid destroying registers. */
44 break;
45 }
Hans Verkuilbd985162005-11-13 16:07:56 -080046
Sri Deevi149783b2009-03-03 06:07:42 -030047 if (!state->is_cx231xx) {
Mauro Carvalho Chehab95b14fb2009-03-03 14:36:55 -030048 /* VID_PLL and AUX_PLL */
49 cx25840_write4(client, 0x108, 0x1006040f);
Sri Deevi149783b2009-03-03 06:07:42 -030050
Mauro Carvalho Chehab95b14fb2009-03-03 14:36:55 -030051 /* AUX_PLL_FRAC */
52 cx25840_write4(client, 0x110, 0x01bb39ee);
Sri Deevi149783b2009-03-03 06:07:42 -030053 }
Hans Verkuilbd985162005-11-13 16:07:56 -080054
Hans Verkuile2b8cf42006-04-22 10:22:46 -030055 if (state->is_cx25836)
56 break;
57
Hans Verkuilbd985162005-11-13 16:07:56 -080058 /* src3/4/6_ctl = 0x0801f77f */
Hans Verkuil4a56eb32007-12-02 07:03:45 -030059 cx25840_write4(client, 0x900, 0x0801f77f);
60 cx25840_write4(client, 0x904, 0x0801f77f);
61 cx25840_write4(client, 0x90c, 0x0801f77f);
Hans Verkuilbd985162005-11-13 16:07:56 -080062 break;
63
Hans Verkuil3578d3d2006-01-09 15:25:41 -020064 case 44100:
Steven Tothf2340812008-01-10 01:22:39 -030065 if (state->is_cx23885) {
66 /* We don't have register values
67 * so avoid destroying registers. */
68 break;
69 }
Hans Verkuilbd985162005-11-13 16:07:56 -080070
Sri Deevi149783b2009-03-03 06:07:42 -030071 if (!state->is_cx231xx) {
Sri Deevi149783b2009-03-03 06:07:42 -030072 /* VID_PLL and AUX_PLL */
73 cx25840_write4(client, 0x108, 0x1009040f);
74
75 /* AUX_PLL_FRAC */
76 cx25840_write4(client, 0x110, 0x00ec6bd6);
77 }
Hans Verkuilbd985162005-11-13 16:07:56 -080078
Hans Verkuile2b8cf42006-04-22 10:22:46 -030079 if (state->is_cx25836)
80 break;
81
Hans Verkuilbd985162005-11-13 16:07:56 -080082 /* src3/4/6_ctl = 0x08016d59 */
Hans Verkuil4a56eb32007-12-02 07:03:45 -030083 cx25840_write4(client, 0x900, 0x08016d59);
84 cx25840_write4(client, 0x904, 0x08016d59);
85 cx25840_write4(client, 0x90c, 0x08016d59);
Hans Verkuilbd985162005-11-13 16:07:56 -080086 break;
87
Hans Verkuil3578d3d2006-01-09 15:25:41 -020088 case 48000:
Steven Tothf2340812008-01-10 01:22:39 -030089 if (state->is_cx23885) {
90 /* We don't have register values
91 * so avoid destroying registers. */
92 break;
93 }
Sri Deevi149783b2009-03-03 06:07:42 -030094
95 if (!state->is_cx231xx) {
Mauro Carvalho Chehab95b14fb2009-03-03 14:36:55 -030096 /* VID_PLL and AUX_PLL */
97 cx25840_write4(client, 0x108, 0x100a040f);
Sri Deevi149783b2009-03-03 06:07:42 -030098
Mauro Carvalho Chehab95b14fb2009-03-03 14:36:55 -030099 /* AUX_PLL_FRAC */
100 cx25840_write4(client, 0x110, 0x0098d6e5);
Sri Deevi149783b2009-03-03 06:07:42 -0300101 }
Hans Verkuilbd985162005-11-13 16:07:56 -0800102
Hans Verkuile2b8cf42006-04-22 10:22:46 -0300103 if (state->is_cx25836)
104 break;
105
Hans Verkuilbd985162005-11-13 16:07:56 -0800106 /* src3/4/6_ctl = 0x08014faa */
Hans Verkuil4a56eb32007-12-02 07:03:45 -0300107 cx25840_write4(client, 0x900, 0x08014faa);
108 cx25840_write4(client, 0x904, 0x08014faa);
109 cx25840_write4(client, 0x90c, 0x08014faa);
Hans Verkuilbd985162005-11-13 16:07:56 -0800110 break;
111 }
Hans Verkuila8bbf122006-01-09 15:25:42 -0200112 } else {
Hans Verkuilbd985162005-11-13 16:07:56 -0800113 switch (freq) {
Hans Verkuil3578d3d2006-01-09 15:25:41 -0200114 case 32000:
Steven Tothf2340812008-01-10 01:22:39 -0300115 if (state->is_cx23885) {
116 /* We don't have register values
117 * so avoid destroying registers. */
118 break;
119 }
Sri Deevi149783b2009-03-03 06:07:42 -0300120
121 if (!state->is_cx231xx) {
Mauro Carvalho Chehab95b14fb2009-03-03 14:36:55 -0300122 /* VID_PLL and AUX_PLL */
123 cx25840_write4(client, 0x108, 0x1e08040f);
Sri Deevi149783b2009-03-03 06:07:42 -0300124
Mauro Carvalho Chehab95b14fb2009-03-03 14:36:55 -0300125 /* AUX_PLL_FRAC */
126 cx25840_write4(client, 0x110, 0x012a0869);
Sri Deevi149783b2009-03-03 06:07:42 -0300127 }
Hans Verkuilbd985162005-11-13 16:07:56 -0800128
Hans Verkuile2b8cf42006-04-22 10:22:46 -0300129 if (state->is_cx25836)
130 break;
131
Hans Verkuilbd985162005-11-13 16:07:56 -0800132 /* src1_ctl = 0x08010000 */
Hans Verkuil4a56eb32007-12-02 07:03:45 -0300133 cx25840_write4(client, 0x8f8, 0x08010000);
Hans Verkuilbd985162005-11-13 16:07:56 -0800134
135 /* src3/4/6_ctl = 0x08020000 */
Hans Verkuil4a56eb32007-12-02 07:03:45 -0300136 cx25840_write4(client, 0x900, 0x08020000);
137 cx25840_write4(client, 0x904, 0x08020000);
138 cx25840_write4(client, 0x90c, 0x08020000);
Hans Verkuilbd985162005-11-13 16:07:56 -0800139
140 /* SA_MCLK_SEL=1, SA_MCLK_DIV=0x14 */
141 cx25840_write(client, 0x127, 0x54);
142 break;
143
Hans Verkuil3578d3d2006-01-09 15:25:41 -0200144 case 44100:
Steven Tothf2340812008-01-10 01:22:39 -0300145 if (state->is_cx23885) {
146 /* We don't have register values
147 * so avoid destroying registers. */
148 break;
149 }
150
Sri Deevi149783b2009-03-03 06:07:42 -0300151
152 if (!state->is_cx231xx) {
Mauro Carvalho Chehab95b14fb2009-03-03 14:36:55 -0300153 /* VID_PLL and AUX_PLL */
154 cx25840_write4(client, 0x108, 0x1809040f);
Sri Deevi149783b2009-03-03 06:07:42 -0300155
Mauro Carvalho Chehab95b14fb2009-03-03 14:36:55 -0300156 /* AUX_PLL_FRAC */
157 cx25840_write4(client, 0x110, 0x00ec6bd6);
Sri Deevi149783b2009-03-03 06:07:42 -0300158 }
Hans Verkuilbd985162005-11-13 16:07:56 -0800159
Hans Verkuile2b8cf42006-04-22 10:22:46 -0300160 if (state->is_cx25836)
161 break;
162
Hans Verkuilbd985162005-11-13 16:07:56 -0800163 /* src1_ctl = 0x08010000 */
Hans Verkuil4a56eb32007-12-02 07:03:45 -0300164 cx25840_write4(client, 0x8f8, 0x080160cd);
Hans Verkuilbd985162005-11-13 16:07:56 -0800165
166 /* src3/4/6_ctl = 0x08020000 */
Hans Verkuil4a56eb32007-12-02 07:03:45 -0300167 cx25840_write4(client, 0x900, 0x08017385);
168 cx25840_write4(client, 0x904, 0x08017385);
169 cx25840_write4(client, 0x90c, 0x08017385);
Hans Verkuilbd985162005-11-13 16:07:56 -0800170 break;
171
Hans Verkuil3578d3d2006-01-09 15:25:41 -0200172 case 48000:
Sri Deevi149783b2009-03-03 06:07:42 -0300173 if (!state->is_cx23885 && !state->is_cx231xx) {
Steven Tothf2340812008-01-10 01:22:39 -0300174 /* VID_PLL and AUX_PLL */
175 cx25840_write4(client, 0x108, 0x180a040f);
Hans Verkuilbd985162005-11-13 16:07:56 -0800176
Steven Tothf2340812008-01-10 01:22:39 -0300177 /* AUX_PLL_FRAC */
178 cx25840_write4(client, 0x110, 0x0098d6e5);
179 }
Hans Verkuilbd985162005-11-13 16:07:56 -0800180
Hans Verkuile2b8cf42006-04-22 10:22:46 -0300181 if (state->is_cx25836)
182 break;
183
Sri Deevi149783b2009-03-03 06:07:42 -0300184 if (!state->is_cx23885 && !state->is_cx231xx) {
Steven Tothf2340812008-01-10 01:22:39 -0300185 /* src1_ctl */
186 cx25840_write4(client, 0x8f8, 0x08018000);
Hans Verkuilbd985162005-11-13 16:07:56 -0800187
Steven Tothf2340812008-01-10 01:22:39 -0300188 /* src3/4/6_ctl */
189 cx25840_write4(client, 0x900, 0x08015555);
190 cx25840_write4(client, 0x904, 0x08015555);
191 cx25840_write4(client, 0x90c, 0x08015555);
192 } else {
193
194 cx25840_write4(client, 0x8f8, 0x0801867c);
195
196 cx25840_write4(client, 0x900, 0x08014faa);
197 cx25840_write4(client, 0x904, 0x08014faa);
198 cx25840_write4(client, 0x90c, 0x08014faa);
199 }
Hans Verkuilbd985162005-11-13 16:07:56 -0800200 break;
201 }
Hans Verkuilbd985162005-11-13 16:07:56 -0800202 }
203
Hans Verkuilbd985162005-11-13 16:07:56 -0800204 state->audclk_freq = freq;
205
206 return 0;
207}
208
Hans Verkuila8bbf122006-01-09 15:25:42 -0200209void cx25840_audio_set_path(struct i2c_client *client)
Hans Verkuilbd985162005-11-13 16:07:56 -0800210{
Hans Verkuil9357b312008-11-29 12:50:06 -0300211 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
Hans Verkuilbd985162005-11-13 16:07:56 -0800212
Hans Verkuil82677612007-08-07 07:16:07 -0300213 /* assert soft reset */
214 cx25840_and_or(client, 0x810, ~0x1, 0x01);
215
Hans Verkuilbd985162005-11-13 16:07:56 -0800216 /* stop microcontroller */
217 cx25840_and_or(client, 0x803, ~0x10, 0);
218
219 /* Mute everything to prevent the PFFT! */
220 cx25840_write(client, 0x8d3, 0x1f);
221
Hans Verkuila8bbf122006-01-09 15:25:42 -0200222 if (state->aud_input == CX25840_AUDIO_SERIAL) {
Hans Verkuilbd985162005-11-13 16:07:56 -0800223 /* Set Path1 to Serial Audio Input */
Hans Verkuil4a56eb32007-12-02 07:03:45 -0300224 cx25840_write4(client, 0x8d0, 0x01011012);
Hans Verkuilbd985162005-11-13 16:07:56 -0800225
226 /* The microcontroller should not be started for the
227 * non-tuner inputs: autodetection is specific for
228 * TV audio. */
Hans Verkuila8bbf122006-01-09 15:25:42 -0200229 } else {
230 /* Set Path1 to Analog Demod Main Channel */
Hans Verkuil4a56eb32007-12-02 07:03:45 -0300231 cx25840_write4(client, 0x8d0, 0x1f063870);
Hans Verkuilc0c044a2006-04-29 12:11:18 -0300232 }
Hans Verkuilbd985162005-11-13 16:07:56 -0800233
Hans Verkuilc0c044a2006-04-29 12:11:18 -0300234 set_audclk_freq(client, state->audclk_freq);
235
236 if (state->aud_input != CX25840_AUDIO_SERIAL) {
Hans Verkuila8bbf122006-01-09 15:25:42 -0200237 /* When the microcontroller detects the
238 * audio format, it will unmute the lines */
239 cx25840_and_or(client, 0x803, ~0x10, 0x10);
Hans Verkuilbd985162005-11-13 16:07:56 -0800240 }
Hans Verkuil82677612007-08-07 07:16:07 -0300241
242 /* deassert soft reset */
243 cx25840_and_or(client, 0x810, ~0x1, 0x00);
Steven Tothf2340812008-01-10 01:22:39 -0300244
Mauro Carvalho Chehab95b14fb2009-03-03 14:36:55 -0300245 /* Ensure the controller is running when we exit */
246 if (state->is_cx23885 || state->is_cx231xx)
Steven Tothf2340812008-01-10 01:22:39 -0300247 cx25840_and_or(client, 0x803, ~0x10, 0x10);
Hans Verkuilbd985162005-11-13 16:07:56 -0800248}
249
Hans Verkuild92c20e2006-01-09 15:32:41 -0200250static int get_volume(struct i2c_client *client)
Hans Verkuilbd985162005-11-13 16:07:56 -0800251{
Hans Verkuil9357b312008-11-29 12:50:06 -0300252 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
Hans Verkuil87410da2007-08-05 08:00:36 -0300253 int vol;
254
255 if (state->unmute_volume >= 0)
256 return state->unmute_volume;
257
Hans Verkuilbd985162005-11-13 16:07:56 -0800258 /* Volume runs +18dB to -96dB in 1/2dB steps
259 * change to fit the msp3400 -114dB to +12dB range */
260
261 /* check PATH1_VOLUME */
Hans Verkuil87410da2007-08-05 08:00:36 -0300262 vol = 228 - cx25840_read(client, 0x8d4);
Hans Verkuilbd985162005-11-13 16:07:56 -0800263 vol = (vol / 2) + 23;
264 return vol << 9;
265}
266
Hans Verkuild92c20e2006-01-09 15:32:41 -0200267static void set_volume(struct i2c_client *client, int volume)
Hans Verkuilbd985162005-11-13 16:07:56 -0800268{
Hans Verkuil9357b312008-11-29 12:50:06 -0300269 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
Hans Verkuil87410da2007-08-05 08:00:36 -0300270 int vol;
271
272 if (state->unmute_volume >= 0) {
273 state->unmute_volume = volume;
274 return;
275 }
276
277 /* Convert the volume to msp3400 values (0-127) */
278 vol = volume >> 9;
279
Hans Verkuilbd985162005-11-13 16:07:56 -0800280 /* now scale it up to cx25840 values
281 * -114dB to -96dB maps to 0
282 * this should be 19, but in my testing that was 4dB too loud */
283 if (vol <= 23) {
284 vol = 0;
285 } else {
286 vol -= 23;
287 }
288
289 /* PATH1_VOLUME */
290 cx25840_write(client, 0x8d4, 228 - (vol * 2));
291}
292
Hans Verkuild92c20e2006-01-09 15:32:41 -0200293static int get_bass(struct i2c_client *client)
Hans Verkuilbd985162005-11-13 16:07:56 -0800294{
295 /* bass is 49 steps +12dB to -12dB */
296
297 /* check PATH1_EQ_BASS_VOL */
298 int bass = cx25840_read(client, 0x8d9) & 0x3f;
299 bass = (((48 - bass) * 0xffff) + 47) / 48;
300 return bass;
301}
302
Hans Verkuild92c20e2006-01-09 15:32:41 -0200303static void set_bass(struct i2c_client *client, int bass)
Hans Verkuilbd985162005-11-13 16:07:56 -0800304{
305 /* PATH1_EQ_BASS_VOL */
306 cx25840_and_or(client, 0x8d9, ~0x3f, 48 - (bass * 48 / 0xffff));
307}
308
Hans Verkuild92c20e2006-01-09 15:32:41 -0200309static int get_treble(struct i2c_client *client)
Hans Verkuilbd985162005-11-13 16:07:56 -0800310{
311 /* treble is 49 steps +12dB to -12dB */
312
313 /* check PATH1_EQ_TREBLE_VOL */
314 int treble = cx25840_read(client, 0x8db) & 0x3f;
315 treble = (((48 - treble) * 0xffff) + 47) / 48;
316 return treble;
317}
318
Hans Verkuild92c20e2006-01-09 15:32:41 -0200319static void set_treble(struct i2c_client *client, int treble)
Hans Verkuilbd985162005-11-13 16:07:56 -0800320{
321 /* PATH1_EQ_TREBLE_VOL */
322 cx25840_and_or(client, 0x8db, ~0x3f, 48 - (treble * 48 / 0xffff));
323}
324
Hans Verkuild92c20e2006-01-09 15:32:41 -0200325static int get_balance(struct i2c_client *client)
Hans Verkuilbd985162005-11-13 16:07:56 -0800326{
327 /* balance is 7 bit, 0 to -96dB */
328
329 /* check PATH1_BAL_LEVEL */
330 int balance = cx25840_read(client, 0x8d5) & 0x7f;
331 /* check PATH1_BAL_LEFT */
332 if ((cx25840_read(client, 0x8d5) & 0x80) == 0)
333 balance = 0x80 - balance;
334 else
335 balance = 0x80 + balance;
336 return balance << 8;
337}
338
Hans Verkuild92c20e2006-01-09 15:32:41 -0200339static void set_balance(struct i2c_client *client, int balance)
Hans Verkuilbd985162005-11-13 16:07:56 -0800340{
341 int bal = balance >> 8;
342 if (bal > 0x80) {
343 /* PATH1_BAL_LEFT */
344 cx25840_and_or(client, 0x8d5, 0x7f, 0x80);
345 /* PATH1_BAL_LEVEL */
346 cx25840_and_or(client, 0x8d5, ~0x7f, bal & 0x7f);
347 } else {
348 /* PATH1_BAL_LEFT */
349 cx25840_and_or(client, 0x8d5, 0x7f, 0x00);
350 /* PATH1_BAL_LEVEL */
351 cx25840_and_or(client, 0x8d5, ~0x7f, 0x80 - bal);
352 }
353}
354
Hans Verkuild92c20e2006-01-09 15:32:41 -0200355static int get_mute(struct i2c_client *client)
Hans Verkuilbd985162005-11-13 16:07:56 -0800356{
Hans Verkuil9357b312008-11-29 12:50:06 -0300357 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
Hans Verkuil87410da2007-08-05 08:00:36 -0300358
359 return state->unmute_volume >= 0;
Hans Verkuilbd985162005-11-13 16:07:56 -0800360}
361
Hans Verkuild92c20e2006-01-09 15:32:41 -0200362static void set_mute(struct i2c_client *client, int mute)
Hans Verkuilbd985162005-11-13 16:07:56 -0800363{
Hans Verkuil9357b312008-11-29 12:50:06 -0300364 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
Hans Verkuilbd985162005-11-13 16:07:56 -0800365
Hans Verkuil87410da2007-08-05 08:00:36 -0300366 if (mute && state->unmute_volume == -1) {
367 int vol = get_volume(client);
368
369 set_volume(client, 0);
370 state->unmute_volume = vol;
371 }
372 else if (!mute && state->unmute_volume != -1) {
373 int vol = state->unmute_volume;
374
375 state->unmute_volume = -1;
376 set_volume(client, vol);
Hans Verkuilbd985162005-11-13 16:07:56 -0800377 }
378}
379
Hans Verkuildf1d5ed2009-03-30 06:26:40 -0300380int cx25840_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
Hans Verkuilbd985162005-11-13 16:07:56 -0800381{
Hans Verkuildf1d5ed2009-03-30 06:26:40 -0300382 struct i2c_client *client = v4l2_get_subdevdata(sd);
383 struct cx25840_state *state = to_state(sd);
Hans Verkuilc0c044a2006-04-29 12:11:18 -0300384 int retval;
Hans Verkuilbd985162005-11-13 16:07:56 -0800385
Hans Verkuildf1d5ed2009-03-30 06:26:40 -0300386 if (!state->is_cx25836)
387 cx25840_and_or(client, 0x810, ~0x1, 1);
388 if (state->aud_input != CX25840_AUDIO_SERIAL) {
389 cx25840_and_or(client, 0x803, ~0x10, 0);
390 cx25840_write(client, 0x8d3, 0x1f);
391 }
392 retval = set_audclk_freq(client, freq);
393 if (state->aud_input != CX25840_AUDIO_SERIAL)
394 cx25840_and_or(client, 0x803, ~0x10, 0x10);
395 if (!state->is_cx25836)
396 cx25840_and_or(client, 0x810, ~0x1, 0);
397 return retval;
398}
Hans Verkuila8bbf122006-01-09 15:25:42 -0200399
Hans Verkuildf1d5ed2009-03-30 06:26:40 -0300400int cx25840_audio_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
401{
402 struct i2c_client *client = v4l2_get_subdevdata(sd);
403
404 switch (ctrl->id) {
405 case V4L2_CID_AUDIO_VOLUME:
406 ctrl->value = get_volume(client);
Hans Verkuilbd985162005-11-13 16:07:56 -0800407 break;
Hans Verkuildf1d5ed2009-03-30 06:26:40 -0300408 case V4L2_CID_AUDIO_BASS:
409 ctrl->value = get_bass(client);
Hans Verkuilbd985162005-11-13 16:07:56 -0800410 break;
Hans Verkuildf1d5ed2009-03-30 06:26:40 -0300411 case V4L2_CID_AUDIO_TREBLE:
412 ctrl->value = get_treble(client);
413 break;
414 case V4L2_CID_AUDIO_BALANCE:
415 ctrl->value = get_balance(client);
416 break;
417 case V4L2_CID_AUDIO_MUTE:
418 ctrl->value = get_mute(client);
419 break;
Hans Verkuilbd985162005-11-13 16:07:56 -0800420 default:
421 return -EINVAL;
422 }
Hans Verkuildf1d5ed2009-03-30 06:26:40 -0300423 return 0;
424}
Hans Verkuilbd985162005-11-13 16:07:56 -0800425
Hans Verkuildf1d5ed2009-03-30 06:26:40 -0300426int cx25840_audio_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
427{
428 struct i2c_client *client = v4l2_get_subdevdata(sd);
429
430 switch (ctrl->id) {
431 case V4L2_CID_AUDIO_VOLUME:
432 set_volume(client, ctrl->value);
433 break;
434 case V4L2_CID_AUDIO_BASS:
435 set_bass(client, ctrl->value);
436 break;
437 case V4L2_CID_AUDIO_TREBLE:
438 set_treble(client, ctrl->value);
439 break;
440 case V4L2_CID_AUDIO_BALANCE:
441 set_balance(client, ctrl->value);
442 break;
443 case V4L2_CID_AUDIO_MUTE:
444 set_mute(client, ctrl->value);
445 break;
446 default:
447 return -EINVAL;
448 }
Hans Verkuilbd985162005-11-13 16:07:56 -0800449 return 0;
450}