This source file includes following definitions.
- set_audclk_freq
- cx18_av_audio_set_path
- set_volume
- set_bass
- set_treble
- set_balance
- set_mute
- cx18_av_s_clock_freq
- cx18_av_audio_s_ctrl
1
2
3
4
5
6
7
8
9
10
11 #include "cx18-driver.h"
12
13 static int set_audclk_freq(struct cx18 *cx, u32 freq)
14 {
15 struct cx18_av_state *state = &cx->av_state;
16
17 if (freq != 32000 && freq != 44100 && freq != 48000)
18 return -EINVAL;
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56 if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
57 switch (freq) {
58 case 32000:
59
60
61
62
63 cx18_av_write4(cx, 0x108, 0x200d040f);
64
65
66
67 cx18_av_write4(cx, 0x10c, 0x002be2fe);
68
69
70
71 cx18_av_write4(cx, 0x110, 0x0176740c);
72
73
74
75 cx18_av_write4(cx, 0x900, 0x0801f77f);
76 cx18_av_write4(cx, 0x904, 0x0801f77f);
77 cx18_av_write4(cx, 0x90c, 0x0801f77f);
78
79
80 cx18_av_write(cx, 0x127, 0x60);
81
82
83 cx18_av_write4(cx, 0x12c, 0x11202fff);
84
85
86
87
88
89
90 cx18_av_write4(cx, 0x128, 0xa00d2ef8);
91 break;
92
93 case 44100:
94
95
96
97
98 cx18_av_write4(cx, 0x108, 0x180e040f);
99
100
101
102 cx18_av_write4(cx, 0x10c, 0x002be2fe);
103
104
105
106 cx18_av_write4(cx, 0x110, 0x0062a1f2);
107
108
109
110 cx18_av_write4(cx, 0x900, 0x08016d59);
111 cx18_av_write4(cx, 0x904, 0x08016d59);
112 cx18_av_write4(cx, 0x90c, 0x08016d59);
113
114
115 cx18_av_write(cx, 0x127, 0x58);
116
117
118 cx18_av_write4(cx, 0x12c, 0x112092ff);
119
120
121
122
123
124
125 cx18_av_write4(cx, 0x128, 0xa01d4bf8);
126 break;
127
128 case 48000:
129
130
131
132
133 cx18_av_write4(cx, 0x108, 0x160e040f);
134
135
136
137 cx18_av_write4(cx, 0x10c, 0x002be2fe);
138
139
140
141 cx18_av_write4(cx, 0x110, 0x005227ad);
142
143
144
145 cx18_av_write4(cx, 0x900, 0x08014faa);
146 cx18_av_write4(cx, 0x904, 0x08014faa);
147 cx18_av_write4(cx, 0x90c, 0x08014faa);
148
149
150 cx18_av_write(cx, 0x127, 0x56);
151
152
153 cx18_av_write4(cx, 0x12c, 0x11205fff);
154
155
156
157
158
159
160 cx18_av_write4(cx, 0x128, 0xa01193f8);
161 break;
162 }
163 } else {
164 switch (freq) {
165 case 32000:
166
167
168
169
170 cx18_av_write4(cx, 0x108, 0x300d040f);
171
172
173
174 cx18_av_write4(cx, 0x10c, 0x002be2fe);
175
176
177
178 cx18_av_write4(cx, 0x110, 0x0176740c);
179
180
181
182 cx18_av_write4(cx, 0x8f8, 0x08010000);
183
184
185
186 cx18_av_write4(cx, 0x900, 0x08020000);
187 cx18_av_write4(cx, 0x904, 0x08020000);
188 cx18_av_write4(cx, 0x90c, 0x08020000);
189
190
191 cx18_av_write(cx, 0x127, 0x70);
192
193
194 cx18_av_write4(cx, 0x12c, 0x11201fff);
195
196
197
198
199
200
201 cx18_av_write4(cx, 0x128, 0xa00d2ef8);
202 break;
203
204 case 44100:
205
206
207
208
209 cx18_av_write4(cx, 0x108, 0x240e040f);
210
211
212
213 cx18_av_write4(cx, 0x10c, 0x002be2fe);
214
215
216
217 cx18_av_write4(cx, 0x110, 0x0062a1f2);
218
219
220
221 cx18_av_write4(cx, 0x8f8, 0x080160cd);
222
223
224
225 cx18_av_write4(cx, 0x900, 0x08017385);
226 cx18_av_write4(cx, 0x904, 0x08017385);
227 cx18_av_write4(cx, 0x90c, 0x08017385);
228
229
230 cx18_av_write(cx, 0x127, 0x64);
231
232
233 cx18_av_write4(cx, 0x12c, 0x112061ff);
234
235
236
237
238
239
240 cx18_av_write4(cx, 0x128, 0xa01d4bf8);
241 break;
242
243 case 48000:
244
245
246
247
248 cx18_av_write4(cx, 0x108, 0x200d040f);
249
250
251
252 cx18_av_write4(cx, 0x10c, 0x002be2fe);
253
254
255
256 cx18_av_write4(cx, 0x110, 0x0176740c);
257
258
259
260 cx18_av_write4(cx, 0x8f8, 0x08018000);
261
262
263
264 cx18_av_write4(cx, 0x900, 0x08015555);
265 cx18_av_write4(cx, 0x904, 0x08015555);
266 cx18_av_write4(cx, 0x90c, 0x08015555);
267
268
269 cx18_av_write(cx, 0x127, 0x60);
270
271
272 cx18_av_write4(cx, 0x12c, 0x11203fff);
273
274
275
276
277
278
279 cx18_av_write4(cx, 0x128, 0xa01193f8);
280 break;
281 }
282 }
283
284 state->audclk_freq = freq;
285
286 return 0;
287 }
288
289 void cx18_av_audio_set_path(struct cx18 *cx)
290 {
291 struct cx18_av_state *state = &cx->av_state;
292 u8 v;
293
294
295 v = cx18_av_read(cx, 0x803) & ~0x10;
296 cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
297
298
299 v = cx18_av_read(cx, 0x810) | 0x01;
300 cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
301
302
303 cx18_av_write(cx, 0x8d3, 0x1f);
304
305 if (state->aud_input <= CX18_AV_AUDIO_SERIAL2) {
306
307 cx18_av_write4(cx, 0x8d0, 0x01011012);
308
309
310
311
312 } else {
313
314 cx18_av_write4(cx, 0x8d0, 0x1f063870);
315 }
316
317 set_audclk_freq(cx, state->audclk_freq);
318
319
320 v = cx18_av_read(cx, 0x810) & ~0x01;
321 cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
322
323 if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
324
325
326 v = cx18_av_read(cx, 0x803) | 0x10;
327 cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
328 }
329 }
330
331 static void set_volume(struct cx18 *cx, int volume)
332 {
333
334 int vol = volume >> 9;
335
336
337
338 if (vol <= 23)
339 vol = 0;
340 else
341 vol -= 23;
342
343
344 cx18_av_write(cx, 0x8d4, 228 - (vol * 2));
345 }
346
347 static void set_bass(struct cx18 *cx, int bass)
348 {
349
350 cx18_av_and_or(cx, 0x8d9, ~0x3f, 48 - (bass * 48 / 0xffff));
351 }
352
353 static void set_treble(struct cx18 *cx, int treble)
354 {
355
356 cx18_av_and_or(cx, 0x8db, ~0x3f, 48 - (treble * 48 / 0xffff));
357 }
358
359 static void set_balance(struct cx18 *cx, int balance)
360 {
361 int bal = balance >> 8;
362 if (bal > 0x80) {
363
364 cx18_av_and_or(cx, 0x8d5, 0x7f, 0x80);
365
366 cx18_av_and_or(cx, 0x8d5, ~0x7f, bal & 0x7f);
367 } else {
368
369 cx18_av_and_or(cx, 0x8d5, 0x7f, 0x00);
370
371 cx18_av_and_or(cx, 0x8d5, ~0x7f, 0x80 - bal);
372 }
373 }
374
375 static void set_mute(struct cx18 *cx, int mute)
376 {
377 struct cx18_av_state *state = &cx->av_state;
378 u8 v;
379
380 if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
381
382
383
384
385 v = cx18_av_read(cx, 0x803);
386 if (mute) {
387
388 v &= ~0x10;
389 cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
390 cx18_av_write(cx, 0x8d3, 0x1f);
391 } else {
392
393 v |= 0x10;
394 cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
395 }
396 } else {
397
398 cx18_av_and_or(cx, 0x8d3, ~0x2, mute ? 0x02 : 0x00);
399 }
400 }
401
402 int cx18_av_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
403 {
404 struct cx18 *cx = v4l2_get_subdevdata(sd);
405 struct cx18_av_state *state = &cx->av_state;
406 int retval;
407 u8 v;
408
409 if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
410 v = cx18_av_read(cx, 0x803) & ~0x10;
411 cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
412 cx18_av_write(cx, 0x8d3, 0x1f);
413 }
414 v = cx18_av_read(cx, 0x810) | 0x1;
415 cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
416
417 retval = set_audclk_freq(cx, freq);
418
419 v = cx18_av_read(cx, 0x810) & ~0x1;
420 cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
421 if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
422 v = cx18_av_read(cx, 0x803) | 0x10;
423 cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
424 }
425 return retval;
426 }
427
428 static int cx18_av_audio_s_ctrl(struct v4l2_ctrl *ctrl)
429 {
430 struct v4l2_subdev *sd = to_sd(ctrl);
431 struct cx18 *cx = v4l2_get_subdevdata(sd);
432
433 switch (ctrl->id) {
434 case V4L2_CID_AUDIO_VOLUME:
435 set_volume(cx, ctrl->val);
436 break;
437 case V4L2_CID_AUDIO_BASS:
438 set_bass(cx, ctrl->val);
439 break;
440 case V4L2_CID_AUDIO_TREBLE:
441 set_treble(cx, ctrl->val);
442 break;
443 case V4L2_CID_AUDIO_BALANCE:
444 set_balance(cx, ctrl->val);
445 break;
446 case V4L2_CID_AUDIO_MUTE:
447 set_mute(cx, ctrl->val);
448 break;
449 default:
450 return -EINVAL;
451 }
452 return 0;
453 }
454
455 const struct v4l2_ctrl_ops cx18_av_audio_ctrl_ops = {
456 .s_ctrl = cx18_av_audio_s_ctrl,
457 };