aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2010-08-06 09:55:39 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2010-08-08 22:43:05 -0400
commite34e658b5a42fb1a12fda2112f0b556cf5d1f1c4 (patch)
tree30adafd463abf3340c1b0fb5920ead9d7159c884 /drivers/media/video
parent72c851b00f6c86353c54fdd9f1ef88d82e8df6c5 (diff)
V4L/DVB: cx25840: convert to the new control framework
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video')
-rw-r--r--drivers/media/video/cx25840/cx25840-audio.c144
-rw-r--r--drivers/media/video/cx25840/cx25840-core.c178
-rw-r--r--drivers/media/video/cx25840/cx25840-core.h18
3 files changed, 94 insertions, 246 deletions
diff --git a/drivers/media/video/cx25840/cx25840-audio.c b/drivers/media/video/cx25840/cx25840-audio.c
index 45608d50529c..6faad34df3ac 100644
--- a/drivers/media/video/cx25840/cx25840-audio.c
+++ b/drivers/media/video/cx25840/cx25840-audio.c
@@ -474,33 +474,10 @@ void cx25840_audio_set_path(struct i2c_client *client)
474 cx25840_and_or(client, 0x803, ~0x10, 0x10); 474 cx25840_and_or(client, 0x803, ~0x10, 0x10);
475} 475}
476 476
477static int get_volume(struct i2c_client *client)
478{
479 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
480 int vol;
481
482 if (state->unmute_volume >= 0)
483 return state->unmute_volume;
484
485 /* Volume runs +18dB to -96dB in 1/2dB steps
486 * change to fit the msp3400 -114dB to +12dB range */
487
488 /* check PATH1_VOLUME */
489 vol = 228 - cx25840_read(client, 0x8d4);
490 vol = (vol / 2) + 23;
491 return vol << 9;
492}
493
494static void set_volume(struct i2c_client *client, int volume) 477static void set_volume(struct i2c_client *client, int volume)
495{ 478{
496 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
497 int vol; 479 int vol;
498 480
499 if (state->unmute_volume >= 0) {
500 state->unmute_volume = volume;
501 return;
502 }
503
504 /* Convert the volume to msp3400 values (0-127) */ 481 /* Convert the volume to msp3400 values (0-127) */
505 vol = volume >> 9; 482 vol = volume >> 9;
506 483
@@ -517,52 +494,6 @@ static void set_volume(struct i2c_client *client, int volume)
517 cx25840_write(client, 0x8d4, 228 - (vol * 2)); 494 cx25840_write(client, 0x8d4, 228 - (vol * 2));
518} 495}
519 496
520static int get_bass(struct i2c_client *client)
521{
522 /* bass is 49 steps +12dB to -12dB */
523
524 /* check PATH1_EQ_BASS_VOL */
525 int bass = cx25840_read(client, 0x8d9) & 0x3f;
526 bass = (((48 - bass) * 0xffff) + 47) / 48;
527 return bass;
528}
529
530static void set_bass(struct i2c_client *client, int bass)
531{
532 /* PATH1_EQ_BASS_VOL */
533 cx25840_and_or(client, 0x8d9, ~0x3f, 48 - (bass * 48 / 0xffff));
534}
535
536static int get_treble(struct i2c_client *client)
537{
538 /* treble is 49 steps +12dB to -12dB */
539
540 /* check PATH1_EQ_TREBLE_VOL */
541 int treble = cx25840_read(client, 0x8db) & 0x3f;
542 treble = (((48 - treble) * 0xffff) + 47) / 48;
543 return treble;
544}
545
546static void set_treble(struct i2c_client *client, int treble)
547{
548 /* PATH1_EQ_TREBLE_VOL */
549 cx25840_and_or(client, 0x8db, ~0x3f, 48 - (treble * 48 / 0xffff));
550}
551
552static int get_balance(struct i2c_client *client)
553{
554 /* balance is 7 bit, 0 to -96dB */
555
556 /* check PATH1_BAL_LEVEL */
557 int balance = cx25840_read(client, 0x8d5) & 0x7f;
558 /* check PATH1_BAL_LEFT */
559 if ((cx25840_read(client, 0x8d5) & 0x80) == 0)
560 balance = 0x80 - balance;
561 else
562 balance = 0x80 + balance;
563 return balance << 8;
564}
565
566static void set_balance(struct i2c_client *client, int balance) 497static void set_balance(struct i2c_client *client, int balance)
567{ 498{
568 int bal = balance >> 8; 499 int bal = balance >> 8;
@@ -579,31 +510,6 @@ static void set_balance(struct i2c_client *client, int balance)
579 } 510 }
580} 511}
581 512
582static int get_mute(struct i2c_client *client)
583{
584 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
585
586 return state->unmute_volume >= 0;
587}
588
589static void set_mute(struct i2c_client *client, int mute)
590{
591 struct cx25840_state *state = to_state(i2c_get_clientdata(client));
592
593 if (mute && state->unmute_volume == -1) {
594 int vol = get_volume(client);
595
596 set_volume(client, 0);
597 state->unmute_volume = vol;
598 }
599 else if (!mute && state->unmute_volume != -1) {
600 int vol = state->unmute_volume;
601
602 state->unmute_volume = -1;
603 set_volume(client, vol);
604 }
605}
606
607int cx25840_s_clock_freq(struct v4l2_subdev *sd, u32 freq) 513int cx25840_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
608{ 514{
609 struct i2c_client *client = v4l2_get_subdevdata(sd); 515 struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -624,25 +530,31 @@ int cx25840_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
624 return retval; 530 return retval;
625} 531}
626 532
627int cx25840_audio_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 533static int cx25840_audio_s_ctrl(struct v4l2_ctrl *ctrl)
628{ 534{
535 struct v4l2_subdev *sd = to_sd(ctrl);
536 struct cx25840_state *state = to_state(sd);
629 struct i2c_client *client = v4l2_get_subdevdata(sd); 537 struct i2c_client *client = v4l2_get_subdevdata(sd);
630 538
631 switch (ctrl->id) { 539 switch (ctrl->id) {
632 case V4L2_CID_AUDIO_VOLUME: 540 case V4L2_CID_AUDIO_VOLUME:
633 ctrl->value = get_volume(client); 541 if (state->mute->val)
542 set_volume(client, 0);
543 else
544 set_volume(client, state->volume->val);
634 break; 545 break;
635 case V4L2_CID_AUDIO_BASS: 546 case V4L2_CID_AUDIO_BASS:
636 ctrl->value = get_bass(client); 547 /* PATH1_EQ_BASS_VOL */
548 cx25840_and_or(client, 0x8d9, ~0x3f,
549 48 - (ctrl->val * 48 / 0xffff));
637 break; 550 break;
638 case V4L2_CID_AUDIO_TREBLE: 551 case V4L2_CID_AUDIO_TREBLE:
639 ctrl->value = get_treble(client); 552 /* PATH1_EQ_TREBLE_VOL */
553 cx25840_and_or(client, 0x8db, ~0x3f,
554 48 - (ctrl->val * 48 / 0xffff));
640 break; 555 break;
641 case V4L2_CID_AUDIO_BALANCE: 556 case V4L2_CID_AUDIO_BALANCE:
642 ctrl->value = get_balance(client); 557 set_balance(client, ctrl->val);
643 break;
644 case V4L2_CID_AUDIO_MUTE:
645 ctrl->value = get_mute(client);
646 break; 558 break;
647 default: 559 default:
648 return -EINVAL; 560 return -EINVAL;
@@ -650,28 +562,6 @@ int cx25840_audio_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
650 return 0; 562 return 0;
651} 563}
652 564
653int cx25840_audio_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 565const struct v4l2_ctrl_ops cx25840_audio_ctrl_ops = {
654{ 566 .s_ctrl = cx25840_audio_s_ctrl,
655 struct i2c_client *client = v4l2_get_subdevdata(sd); 567};
656
657 switch (ctrl->id) {
658 case V4L2_CID_AUDIO_VOLUME:
659 set_volume(client, ctrl->value);
660 break;
661 case V4L2_CID_AUDIO_BASS:
662 set_bass(client, ctrl->value);
663 break;
664 case V4L2_CID_AUDIO_TREBLE:
665 set_treble(client, ctrl->value);
666 break;
667 case V4L2_CID_AUDIO_BALANCE:
668 set_balance(client, ctrl->value);
669 break;
670 case V4L2_CID_AUDIO_MUTE:
671 set_mute(client, ctrl->value);
672 break;
673 default:
674 return -EINVAL;
675 }
676 return 0;
677}
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c
index 69763729ccc6..86ca8c2359dd 100644
--- a/drivers/media/video/cx25840/cx25840-core.c
+++ b/drivers/media/video/cx25840/cx25840-core.c
@@ -1121,94 +1121,29 @@ static int set_v4lstd(struct i2c_client *client)
1121 1121
1122/* ----------------------------------------------------------------------- */ 1122/* ----------------------------------------------------------------------- */
1123 1123
1124static int cx25840_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 1124static int cx25840_s_ctrl(struct v4l2_ctrl *ctrl)
1125{ 1125{
1126 struct cx25840_state *state = to_state(sd); 1126 struct v4l2_subdev *sd = to_sd(ctrl);
1127 struct i2c_client *client = v4l2_get_subdevdata(sd); 1127 struct i2c_client *client = v4l2_get_subdevdata(sd);
1128 1128
1129 switch (ctrl->id) { 1129 switch (ctrl->id) {
1130 case V4L2_CID_BRIGHTNESS: 1130 case V4L2_CID_BRIGHTNESS:
1131 if (ctrl->value < 0 || ctrl->value > 255) { 1131 cx25840_write(client, 0x414, ctrl->val - 128);
1132 v4l_err(client, "invalid brightness setting %d\n",
1133 ctrl->value);
1134 return -ERANGE;
1135 }
1136
1137 cx25840_write(client, 0x414, ctrl->value - 128);
1138 break; 1132 break;
1139 1133
1140 case V4L2_CID_CONTRAST: 1134 case V4L2_CID_CONTRAST:
1141 if (ctrl->value < 0 || ctrl->value > 127) { 1135 cx25840_write(client, 0x415, ctrl->val << 1);
1142 v4l_err(client, "invalid contrast setting %d\n",
1143 ctrl->value);
1144 return -ERANGE;
1145 }
1146
1147 cx25840_write(client, 0x415, ctrl->value << 1);
1148 break; 1136 break;
1149 1137
1150 case V4L2_CID_SATURATION: 1138 case V4L2_CID_SATURATION:
1151 if (ctrl->value < 0 || ctrl->value > 127) { 1139 cx25840_write(client, 0x420, ctrl->val << 1);
1152 v4l_err(client, "invalid saturation setting %d\n", 1140 cx25840_write(client, 0x421, ctrl->val << 1);
1153 ctrl->value);
1154 return -ERANGE;
1155 }
1156
1157 cx25840_write(client, 0x420, ctrl->value << 1);
1158 cx25840_write(client, 0x421, ctrl->value << 1);
1159 break; 1141 break;
1160 1142
1161 case V4L2_CID_HUE: 1143 case V4L2_CID_HUE:
1162 if (ctrl->value < -128 || ctrl->value > 127) { 1144 cx25840_write(client, 0x422, ctrl->val);
1163 v4l_err(client, "invalid hue setting %d\n", ctrl->value);
1164 return -ERANGE;
1165 }
1166
1167 cx25840_write(client, 0x422, ctrl->value);
1168 break; 1145 break;
1169 1146
1170 case V4L2_CID_AUDIO_VOLUME:
1171 case V4L2_CID_AUDIO_BASS:
1172 case V4L2_CID_AUDIO_TREBLE:
1173 case V4L2_CID_AUDIO_BALANCE:
1174 case V4L2_CID_AUDIO_MUTE:
1175 if (is_cx2583x(state))
1176 return -EINVAL;
1177 return cx25840_audio_s_ctrl(sd, ctrl);
1178
1179 default:
1180 return -EINVAL;
1181 }
1182
1183 return 0;
1184}
1185
1186static int cx25840_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
1187{
1188 struct cx25840_state *state = to_state(sd);
1189 struct i2c_client *client = v4l2_get_subdevdata(sd);
1190
1191 switch (ctrl->id) {
1192 case V4L2_CID_BRIGHTNESS:
1193 ctrl->value = (s8)cx25840_read(client, 0x414) + 128;
1194 break;
1195 case V4L2_CID_CONTRAST:
1196 ctrl->value = cx25840_read(client, 0x415) >> 1;
1197 break;
1198 case V4L2_CID_SATURATION:
1199 ctrl->value = cx25840_read(client, 0x420) >> 1;
1200 break;
1201 case V4L2_CID_HUE:
1202 ctrl->value = (s8)cx25840_read(client, 0x422);
1203 break;
1204 case V4L2_CID_AUDIO_VOLUME:
1205 case V4L2_CID_AUDIO_BASS:
1206 case V4L2_CID_AUDIO_TREBLE:
1207 case V4L2_CID_AUDIO_BALANCE:
1208 case V4L2_CID_AUDIO_MUTE:
1209 if (is_cx2583x(state))
1210 return -EINVAL;
1211 return cx25840_audio_g_ctrl(sd, ctrl);
1212 default: 1147 default:
1213 return -EINVAL; 1148 return -EINVAL;
1214 } 1149 }
@@ -1367,8 +1302,6 @@ static void log_audio_status(struct i2c_client *client)
1367 default: p = "not defined"; 1302 default: p = "not defined";
1368 } 1303 }
1369 v4l_info(client, "Detected audio standard: %s\n", p); 1304 v4l_info(client, "Detected audio standard: %s\n", p);
1370 v4l_info(client, "Audio muted: %s\n",
1371 (state->unmute_volume >= 0) ? "yes" : "no");
1372 v4l_info(client, "Audio microcontroller: %s\n", 1305 v4l_info(client, "Audio microcontroller: %s\n",
1373 (download_ctl & 0x10) ? 1306 (download_ctl & 0x10) ?
1374 ((mute_ctl & 0x2) ? "detecting" : "running") : "stopped"); 1307 ((mute_ctl & 0x2) ? "detecting" : "running") : "stopped");
@@ -1585,40 +1518,6 @@ static int cx25840_s_stream(struct v4l2_subdev *sd, int enable)
1585 return 0; 1518 return 0;
1586} 1519}
1587 1520
1588static int cx25840_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
1589{
1590 struct cx25840_state *state = to_state(sd);
1591
1592 switch (qc->id) {
1593 case V4L2_CID_BRIGHTNESS:
1594 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
1595 case V4L2_CID_CONTRAST:
1596 case V4L2_CID_SATURATION:
1597 return v4l2_ctrl_query_fill(qc, 0, 127, 1, 64);
1598 case V4L2_CID_HUE:
1599 return v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
1600 default:
1601 break;
1602 }
1603 if (is_cx2583x(state))
1604 return -EINVAL;
1605
1606 switch (qc->id) {
1607 case V4L2_CID_AUDIO_VOLUME:
1608 return v4l2_ctrl_query_fill(qc, 0, 65535,
1609 65535 / 100, state->default_volume);
1610 case V4L2_CID_AUDIO_MUTE:
1611 return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
1612 case V4L2_CID_AUDIO_BALANCE:
1613 case V4L2_CID_AUDIO_BASS:
1614 case V4L2_CID_AUDIO_TREBLE:
1615 return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 32768);
1616 default:
1617 return -EINVAL;
1618 }
1619 return -EINVAL;
1620}
1621
1622static int cx25840_s_std(struct v4l2_subdev *sd, v4l2_std_id std) 1521static int cx25840_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
1623{ 1522{
1624 struct cx25840_state *state = to_state(sd); 1523 struct cx25840_state *state = to_state(sd);
@@ -1781,6 +1680,7 @@ static int cx25840_log_status(struct v4l2_subdev *sd)
1781 if (!is_cx2583x(state)) 1680 if (!is_cx2583x(state))
1782 log_audio_status(client); 1681 log_audio_status(client);
1783 cx25840_ir_log_status(sd); 1682 cx25840_ir_log_status(sd);
1683 v4l2_ctrl_handler_log_status(&state->hdl, sd->name);
1784 return 0; 1684 return 0;
1785} 1685}
1786 1686
@@ -1883,13 +1783,21 @@ static int cx25840_irq_handler(struct v4l2_subdev *sd, u32 status,
1883 1783
1884/* ----------------------------------------------------------------------- */ 1784/* ----------------------------------------------------------------------- */
1885 1785
1786static const struct v4l2_ctrl_ops cx25840_ctrl_ops = {
1787 .s_ctrl = cx25840_s_ctrl,
1788};
1789
1886static const struct v4l2_subdev_core_ops cx25840_core_ops = { 1790static const struct v4l2_subdev_core_ops cx25840_core_ops = {
1887 .log_status = cx25840_log_status, 1791 .log_status = cx25840_log_status,
1888 .s_config = cx25840_s_config, 1792 .s_config = cx25840_s_config,
1889 .g_chip_ident = cx25840_g_chip_ident, 1793 .g_chip_ident = cx25840_g_chip_ident,
1890 .g_ctrl = cx25840_g_ctrl, 1794 .g_ctrl = v4l2_subdev_g_ctrl,
1891 .s_ctrl = cx25840_s_ctrl, 1795 .s_ctrl = v4l2_subdev_s_ctrl,
1892 .queryctrl = cx25840_queryctrl, 1796 .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
1797 .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
1798 .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
1799 .queryctrl = v4l2_subdev_queryctrl,
1800 .querymenu = v4l2_subdev_querymenu,
1893 .s_std = cx25840_s_std, 1801 .s_std = cx25840_s_std,
1894 .reset = cx25840_reset, 1802 .reset = cx25840_reset,
1895 .load_fw = cx25840_load_fw, 1803 .load_fw = cx25840_load_fw,
@@ -1981,6 +1889,7 @@ static int cx25840_probe(struct i2c_client *client,
1981{ 1889{
1982 struct cx25840_state *state; 1890 struct cx25840_state *state;
1983 struct v4l2_subdev *sd; 1891 struct v4l2_subdev *sd;
1892 int default_volume;
1984 u32 id = V4L2_IDENT_NONE; 1893 u32 id = V4L2_IDENT_NONE;
1985 u16 device_id; 1894 u16 device_id;
1986 1895
@@ -2024,6 +1933,7 @@ static int cx25840_probe(struct i2c_client *client,
2024 1933
2025 sd = &state->sd; 1934 sd = &state->sd;
2026 v4l2_i2c_subdev_init(sd, client, &cx25840_ops); 1935 v4l2_i2c_subdev_init(sd, client, &cx25840_ops);
1936
2027 switch (id) { 1937 switch (id) {
2028 case V4L2_IDENT_CX23885_AV: 1938 case V4L2_IDENT_CX23885_AV:
2029 v4l_info(client, "cx23885 A/V decoder found @ 0x%x (%s)\n", 1939 v4l_info(client, "cx23885 A/V decoder found @ 0x%x (%s)\n",
@@ -2068,12 +1978,48 @@ static int cx25840_probe(struct i2c_client *client,
2068 state->audclk_freq = 48000; 1978 state->audclk_freq = 48000;
2069 state->pvr150_workaround = 0; 1979 state->pvr150_workaround = 0;
2070 state->audmode = V4L2_TUNER_MODE_LANG1; 1980 state->audmode = V4L2_TUNER_MODE_LANG1;
2071 state->unmute_volume = -1;
2072 state->default_volume = 228 - cx25840_read(client, 0x8d4);
2073 state->default_volume = ((state->default_volume / 2) + 23) << 9;
2074 state->vbi_line_offset = 8; 1981 state->vbi_line_offset = 8;
2075 state->id = id; 1982 state->id = id;
2076 state->rev = device_id; 1983 state->rev = device_id;
1984 v4l2_ctrl_handler_init(&state->hdl, 9);
1985 v4l2_ctrl_new_std(&state->hdl, &cx25840_ctrl_ops,
1986 V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
1987 v4l2_ctrl_new_std(&state->hdl, &cx25840_ctrl_ops,
1988 V4L2_CID_CONTRAST, 0, 127, 1, 64);
1989 v4l2_ctrl_new_std(&state->hdl, &cx25840_ctrl_ops,
1990 V4L2_CID_SATURATION, 0, 127, 1, 64);
1991 v4l2_ctrl_new_std(&state->hdl, &cx25840_ctrl_ops,
1992 V4L2_CID_HUE, -128, 127, 1, 0);
1993 if (!is_cx2583x(state)) {
1994 default_volume = 228 - cx25840_read(client, 0x8d4);
1995 default_volume = ((default_volume / 2) + 23) << 9;
1996
1997 state->volume = v4l2_ctrl_new_std(&state->hdl,
1998 &cx25840_audio_ctrl_ops, V4L2_CID_AUDIO_VOLUME,
1999 0, 65335, 65535 / 100, default_volume);
2000 state->mute = v4l2_ctrl_new_std(&state->hdl,
2001 &cx25840_audio_ctrl_ops, V4L2_CID_AUDIO_MUTE,
2002 0, 1, 1, 0);
2003 v4l2_ctrl_new_std(&state->hdl, &cx25840_audio_ctrl_ops,
2004 V4L2_CID_AUDIO_BALANCE,
2005 0, 65535, 65535 / 100, 32768);
2006 v4l2_ctrl_new_std(&state->hdl, &cx25840_audio_ctrl_ops,
2007 V4L2_CID_AUDIO_BASS,
2008 0, 65535, 65535 / 100, 32768);
2009 v4l2_ctrl_new_std(&state->hdl, &cx25840_audio_ctrl_ops,
2010 V4L2_CID_AUDIO_TREBLE,
2011 0, 65535, 65535 / 100, 32768);
2012 }
2013 sd->ctrl_handler = &state->hdl;
2014 if (state->hdl.error) {
2015 int err = state->hdl.error;
2016
2017 v4l2_ctrl_handler_free(&state->hdl);
2018 kfree(state);
2019 return err;
2020 }
2021 v4l2_ctrl_cluster(2, &state->volume);
2022 v4l2_ctrl_handler_setup(&state->hdl);
2077 2023
2078 cx25840_ir_probe(sd); 2024 cx25840_ir_probe(sd);
2079 return 0; 2025 return 0;
@@ -2082,10 +2028,12 @@ static int cx25840_probe(struct i2c_client *client,
2082static int cx25840_remove(struct i2c_client *client) 2028static int cx25840_remove(struct i2c_client *client)
2083{ 2029{
2084 struct v4l2_subdev *sd = i2c_get_clientdata(client); 2030 struct v4l2_subdev *sd = i2c_get_clientdata(client);
2031 struct cx25840_state *state = to_state(sd);
2085 2032
2086 cx25840_ir_remove(sd); 2033 cx25840_ir_remove(sd);
2087 v4l2_device_unregister_subdev(sd); 2034 v4l2_device_unregister_subdev(sd);
2088 kfree(to_state(sd)); 2035 v4l2_ctrl_handler_free(&state->hdl);
2036 kfree(state);
2089 return 0; 2037 return 0;
2090} 2038}
2091 2039
diff --git a/drivers/media/video/cx25840/cx25840-core.h b/drivers/media/video/cx25840/cx25840-core.h
index 8ac57a13a455..bd4ada28b490 100644
--- a/drivers/media/video/cx25840/cx25840-core.h
+++ b/drivers/media/video/cx25840/cx25840-core.h
@@ -24,6 +24,7 @@
24#include <linux/videodev2.h> 24#include <linux/videodev2.h>
25#include <media/v4l2-device.h> 25#include <media/v4l2-device.h>
26#include <media/v4l2-chip-ident.h> 26#include <media/v4l2-chip-ident.h>
27#include <media/v4l2-ctrls.h>
27#include <linux/i2c.h> 28#include <linux/i2c.h>
28 29
29struct cx25840_ir_state; 30struct cx25840_ir_state;
@@ -31,6 +32,12 @@ struct cx25840_ir_state;
31struct cx25840_state { 32struct cx25840_state {
32 struct i2c_client *c; 33 struct i2c_client *c;
33 struct v4l2_subdev sd; 34 struct v4l2_subdev sd;
35 struct v4l2_ctrl_handler hdl;
36 struct {
37 /* volume cluster */
38 struct v4l2_ctrl *volume;
39 struct v4l2_ctrl *mute;
40 };
34 int pvr150_workaround; 41 int pvr150_workaround;
35 int radio; 42 int radio;
36 v4l2_std_id std; 43 v4l2_std_id std;
@@ -38,8 +45,6 @@ struct cx25840_state {
38 enum cx25840_audio_input aud_input; 45 enum cx25840_audio_input aud_input;
39 u32 audclk_freq; 46 u32 audclk_freq;
40 int audmode; 47 int audmode;
41 int unmute_volume; /* -1 if not muted */
42 int default_volume;
43 int vbi_line_offset; 48 int vbi_line_offset;
44 u32 id; 49 u32 id;
45 u32 rev; 50 u32 rev;
@@ -54,6 +59,11 @@ static inline struct cx25840_state *to_state(struct v4l2_subdev *sd)
54 return container_of(sd, struct cx25840_state, sd); 59 return container_of(sd, struct cx25840_state, sd);
55} 60}
56 61
62static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
63{
64 return &container_of(ctrl->handler, struct cx25840_state, hdl)->sd;
65}
66
57static inline bool is_cx2583x(struct cx25840_state *state) 67static inline bool is_cx2583x(struct cx25840_state *state)
58{ 68{
59 return state->id == V4L2_IDENT_CX25836 || 69 return state->id == V4L2_IDENT_CX25836 ||
@@ -106,8 +116,8 @@ int cx25840_loadfw(struct i2c_client *client);
106/* cx25850-audio.c */ 116/* cx25850-audio.c */
107void cx25840_audio_set_path(struct i2c_client *client); 117void cx25840_audio_set_path(struct i2c_client *client);
108int cx25840_s_clock_freq(struct v4l2_subdev *sd, u32 freq); 118int cx25840_s_clock_freq(struct v4l2_subdev *sd, u32 freq);
109int cx25840_audio_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl); 119
110int cx25840_audio_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl); 120extern const struct v4l2_ctrl_ops cx25840_audio_ctrl_ops;
111 121
112/* ----------------------------------------------------------------------- */ 122/* ----------------------------------------------------------------------- */
113/* cx25850-vbi.c */ 123/* cx25850-vbi.c */