aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2013-04-08 16:27:18 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-04-14 18:55:22 -0400
commit03aa1bcd92eca82735e1de6d3e71bebf6e1c516e (patch)
tree2b3d56a9a63ab2e66352984f76fd3a0e6c5d6350
parentb387754d7256b1fa3610ed8a85f9274df49d1178 (diff)
[media] radio-si4713: convert to the control framework
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Acked-by: Eduardo Valentin <edubezval@gmail.com> Tested-by: Eduardo Valentin <edubezval@gmail.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/radio/radio-si4713.c89
-rw-r--r--drivers/media/radio/si4713-i2c.c908
-rw-r--r--drivers/media/radio/si4713-i2c.h65
3 files changed, 239 insertions, 823 deletions
diff --git a/drivers/media/radio/radio-si4713.c b/drivers/media/radio/radio-si4713.c
index 633c545438f7..f8c6137573a8 100644
--- a/drivers/media/radio/radio-si4713.c
+++ b/drivers/media/radio/radio-si4713.c
@@ -76,61 +76,6 @@ static int radio_si4713_querycap(struct file *file, void *priv,
76 return 0; 76 return 0;
77} 77}
78 78
79/* radio_si4713_queryctrl - enumerate control items */
80static int radio_si4713_queryctrl(struct file *file, void *priv,
81 struct v4l2_queryctrl *qc)
82{
83 /* Must be sorted from low to high control ID! */
84 static const u32 user_ctrls[] = {
85 V4L2_CID_USER_CLASS,
86 V4L2_CID_AUDIO_MUTE,
87 0
88 };
89
90 /* Must be sorted from low to high control ID! */
91 static const u32 fmtx_ctrls[] = {
92 V4L2_CID_FM_TX_CLASS,
93 V4L2_CID_RDS_TX_DEVIATION,
94 V4L2_CID_RDS_TX_PI,
95 V4L2_CID_RDS_TX_PTY,
96 V4L2_CID_RDS_TX_PS_NAME,
97 V4L2_CID_RDS_TX_RADIO_TEXT,
98 V4L2_CID_AUDIO_LIMITER_ENABLED,
99 V4L2_CID_AUDIO_LIMITER_RELEASE_TIME,
100 V4L2_CID_AUDIO_LIMITER_DEVIATION,
101 V4L2_CID_AUDIO_COMPRESSION_ENABLED,
102 V4L2_CID_AUDIO_COMPRESSION_GAIN,
103 V4L2_CID_AUDIO_COMPRESSION_THRESHOLD,
104 V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME,
105 V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME,
106 V4L2_CID_PILOT_TONE_ENABLED,
107 V4L2_CID_PILOT_TONE_DEVIATION,
108 V4L2_CID_PILOT_TONE_FREQUENCY,
109 V4L2_CID_TUNE_PREEMPHASIS,
110 V4L2_CID_TUNE_POWER_LEVEL,
111 V4L2_CID_TUNE_ANTENNA_CAPACITOR,
112 0
113 };
114 static const u32 *ctrl_classes[] = {
115 user_ctrls,
116 fmtx_ctrls,
117 NULL
118 };
119 struct radio_si4713_device *rsdev;
120
121 rsdev = video_get_drvdata(video_devdata(file));
122
123 qc->id = v4l2_ctrl_next(ctrl_classes, qc->id);
124 if (qc->id == 0)
125 return -EINVAL;
126
127 if (qc->id == V4L2_CID_USER_CLASS || qc->id == V4L2_CID_FM_TX_CLASS)
128 return v4l2_ctrl_query_fill(qc, 0, 0, 0, 0);
129
130 return v4l2_device_call_until_err(&rsdev->v4l2_dev, 0, core,
131 queryctrl, qc);
132}
133
134/* 79/*
135 * v4l2 ioctl call backs. 80 * v4l2 ioctl call backs.
136 * we are just a wrapper for v4l2_sub_devs. 81 * we are just a wrapper for v4l2_sub_devs.
@@ -140,34 +85,6 @@ static inline struct v4l2_device *get_v4l2_dev(struct file *file)
140 return &((struct radio_si4713_device *)video_drvdata(file))->v4l2_dev; 85 return &((struct radio_si4713_device *)video_drvdata(file))->v4l2_dev;
141} 86}
142 87
143static int radio_si4713_g_ext_ctrls(struct file *file, void *p,
144 struct v4l2_ext_controls *vecs)
145{
146 return v4l2_device_call_until_err(get_v4l2_dev(file), 0, core,
147 g_ext_ctrls, vecs);
148}
149
150static int radio_si4713_s_ext_ctrls(struct file *file, void *p,
151 struct v4l2_ext_controls *vecs)
152{
153 return v4l2_device_call_until_err(get_v4l2_dev(file), 0, core,
154 s_ext_ctrls, vecs);
155}
156
157static int radio_si4713_g_ctrl(struct file *file, void *p,
158 struct v4l2_control *vc)
159{
160 return v4l2_device_call_until_err(get_v4l2_dev(file), 0, core,
161 g_ctrl, vc);
162}
163
164static int radio_si4713_s_ctrl(struct file *file, void *p,
165 struct v4l2_control *vc)
166{
167 return v4l2_device_call_until_err(get_v4l2_dev(file), 0, core,
168 s_ctrl, vc);
169}
170
171static int radio_si4713_g_modulator(struct file *file, void *p, 88static int radio_si4713_g_modulator(struct file *file, void *p,
172 struct v4l2_modulator *vm) 89 struct v4l2_modulator *vm)
173{ 90{
@@ -205,11 +122,6 @@ static long radio_si4713_default(struct file *file, void *p,
205 122
206static struct v4l2_ioctl_ops radio_si4713_ioctl_ops = { 123static struct v4l2_ioctl_ops radio_si4713_ioctl_ops = {
207 .vidioc_querycap = radio_si4713_querycap, 124 .vidioc_querycap = radio_si4713_querycap,
208 .vidioc_queryctrl = radio_si4713_queryctrl,
209 .vidioc_g_ext_ctrls = radio_si4713_g_ext_ctrls,
210 .vidioc_s_ext_ctrls = radio_si4713_s_ext_ctrls,
211 .vidioc_g_ctrl = radio_si4713_g_ctrl,
212 .vidioc_s_ctrl = radio_si4713_s_ctrl,
213 .vidioc_g_modulator = radio_si4713_g_modulator, 125 .vidioc_g_modulator = radio_si4713_g_modulator,
214 .vidioc_s_modulator = radio_si4713_s_modulator, 126 .vidioc_s_modulator = radio_si4713_s_modulator,
215 .vidioc_g_frequency = radio_si4713_g_frequency, 127 .vidioc_g_frequency = radio_si4713_g_frequency,
@@ -274,6 +186,7 @@ static int radio_si4713_pdriver_probe(struct platform_device *pdev)
274 186
275 rsdev->radio_dev = radio_si4713_vdev_template; 187 rsdev->radio_dev = radio_si4713_vdev_template;
276 rsdev->radio_dev.v4l2_dev = &rsdev->v4l2_dev; 188 rsdev->radio_dev.v4l2_dev = &rsdev->v4l2_dev;
189 rsdev->radio_dev.ctrl_handler = sd->ctrl_handler;
277 /* Serialize all access to the si4713 */ 190 /* Serialize all access to the si4713 */
278 rsdev->radio_dev.lock = &rsdev->lock; 191 rsdev->radio_dev.lock = &rsdev->lock;
279 video_set_drvdata(&rsdev->radio_dev, rsdev); 192 video_set_drvdata(&rsdev->radio_dev, rsdev);
diff --git a/drivers/media/radio/si4713-i2c.c b/drivers/media/radio/si4713-i2c.c
index 56c9241ee7fb..fe160882ee10 100644
--- a/drivers/media/radio/si4713-i2c.c
+++ b/drivers/media/radio/si4713-i2c.c
@@ -52,8 +52,6 @@ static const char *si4713_supply_names[SI4713_NUM_SUPPLIES] = {
52 52
53#define DEFAULT_RDS_PI 0x00 53#define DEFAULT_RDS_PI 0x00
54#define DEFAULT_RDS_PTY 0x00 54#define DEFAULT_RDS_PTY 0x00
55#define DEFAULT_RDS_PS_NAME ""
56#define DEFAULT_RDS_RADIO_TEXT DEFAULT_RDS_PS_NAME
57#define DEFAULT_RDS_DEVIATION 0x00C8 55#define DEFAULT_RDS_DEVIATION 0x00C8
58#define DEFAULT_RDS_PS_REPEAT_COUNT 0x0003 56#define DEFAULT_RDS_PS_REPEAT_COUNT 0x0003
59#define DEFAULT_LIMITER_RTIME 0x1392 57#define DEFAULT_LIMITER_RTIME 0x1392
@@ -107,7 +105,6 @@ static const char *si4713_supply_names[SI4713_NUM_SUPPLIES] = {
107 (status & SI4713_ERR)) 105 (status & SI4713_ERR))
108/* mute definition */ 106/* mute definition */
109#define set_mute(p) ((p & 1) | ((p & 1) << 1)); 107#define set_mute(p) ((p & 1) | ((p & 1) << 1));
110#define get_mute(p) (p & 0x01)
111 108
112#ifdef DEBUG 109#ifdef DEBUG
113#define DBG_BUFFER(device, message, buffer, size) \ 110#define DBG_BUFFER(device, message, buffer, size) \
@@ -189,21 +186,6 @@ static int usecs_to_dev(unsigned long usecs, unsigned long const array[],
189 return rval; 186 return rval;
190} 187}
191 188
192static unsigned long dev_to_usecs(int value, unsigned long const array[],
193 int size)
194{
195 int i;
196 int rval = -EINVAL;
197
198 for (i = 0; i < size / 2; i++)
199 if (array[i * 2] == value) {
200 rval = array[(i * 2) + 1];
201 break;
202 }
203
204 return rval;
205}
206
207/* si4713_handler: IRQ handler, just complete work */ 189/* si4713_handler: IRQ handler, just complete work */
208static irqreturn_t si4713_handler(int irq, void *dev) 190static irqreturn_t si4713_handler(int irq, void *dev)
209{ 191{
@@ -787,9 +769,6 @@ static int si4713_set_mute(struct si4713_device *sdev, u16 mute)
787 rval = si4713_write_property(sdev, 769 rval = si4713_write_property(sdev,
788 SI4713_TX_LINE_INPUT_MUTE, mute); 770 SI4713_TX_LINE_INPUT_MUTE, mute);
789 771
790 if (rval >= 0)
791 sdev->mute = get_mute(mute);
792
793 return rval; 772 return rval;
794} 773}
795 774
@@ -830,7 +809,6 @@ static int si4713_set_rds_ps_name(struct si4713_device *sdev, char *ps_name)
830 return rval; 809 return rval;
831 } 810 }
832 811
833 strncpy(sdev->rds_info.ps_name, ps_name, MAX_RDS_PS_NAME);
834 return rval; 812 return rval;
835} 813}
836 814
@@ -842,24 +820,23 @@ static int si4713_set_rds_radio_text(struct si4713_device *sdev, char *rt)
842 s8 left; 820 s8 left;
843 821
844 if (!sdev->power_state) 822 if (!sdev->power_state)
845 goto copy; 823 return rval;
846 824
847 rval = si4713_tx_rds_buff(sdev, RDS_BLOCK_CLEAR, 0, 0, 0, &left); 825 rval = si4713_tx_rds_buff(sdev, RDS_BLOCK_CLEAR, 0, 0, 0, &left);
848 if (rval < 0) 826 if (rval < 0)
849 return rval; 827 return rval;
850 828
851 if (!strlen(rt)) 829 if (!strlen(rt))
852 goto copy; 830 return rval;
853 831
854 do { 832 do {
855 /* RDS spec says that if the last block isn't used, 833 /* RDS spec says that if the last block isn't used,
856 * then apply a carriage return 834 * then apply a carriage return
857 */ 835 */
858 if (t_index < (RDS_RADIOTEXT_INDEX_MAX * 836 if (t_index < (RDS_RADIOTEXT_INDEX_MAX * RDS_RADIOTEXT_BLK_SIZE)) {
859 RDS_RADIOTEXT_BLK_SIZE)) {
860 for (i = 0; i < RDS_RADIOTEXT_BLK_SIZE; i++) { 837 for (i = 0; i < RDS_RADIOTEXT_BLK_SIZE; i++) {
861 if (!rt[t_index + i] || rt[t_index + i] == 838 if (!rt[t_index + i] ||
862 RDS_CARRIAGE_RETURN) { 839 rt[t_index + i] == RDS_CARRIAGE_RETURN) {
863 rt[t_index + i] = RDS_CARRIAGE_RETURN; 840 rt[t_index + i] = RDS_CARRIAGE_RETURN;
864 cr_inserted = 1; 841 cr_inserted = 1;
865 break; 842 break;
@@ -881,13 +858,38 @@ static int si4713_set_rds_radio_text(struct si4713_device *sdev, char *rt)
881 break; 858 break;
882 } while (left > 0); 859 } while (left > 0);
883 860
884copy: 861 return rval;
885 strncpy(sdev->rds_info.radio_text, rt, MAX_RDS_RADIO_TEXT); 862}
863
864/*
865 * si4713_update_tune_status - update properties from tx_tune_status
866 * command. Must be called with sdev->mutex held.
867 * @sdev: si4713_device structure for the device we are communicating
868 */
869static int si4713_update_tune_status(struct si4713_device *sdev)
870{
871 int rval;
872 u16 f = 0;
873 u8 p = 0, a = 0, n = 0;
874
875 rval = si4713_tx_tune_status(sdev, 0x00, &f, &p, &a, &n);
876
877 if (rval < 0)
878 goto exit;
879
880/* TODO: check that power_level and antenna_capacitor really are not
881 changed by the hardware. If they are, then these controls should become
882 volatiles.
883 sdev->power_level = p;
884 sdev->antenna_capacitor = a;*/
885 sdev->tune_rnl = n;
886
887exit:
886 return rval; 888 return rval;
887} 889}
888 890
889static int si4713_choose_econtrol_action(struct si4713_device *sdev, u32 id, 891static int si4713_choose_econtrol_action(struct si4713_device *sdev, u32 id,
890 u32 **shadow, s32 *bit, s32 *mask, u16 *property, int *mul, 892 s32 *bit, s32 *mask, u16 *property, int *mul,
891 unsigned long **table, int *size) 893 unsigned long **table, int *size)
892{ 894{
893 s32 rval = 0; 895 s32 rval = 0;
@@ -897,277 +899,76 @@ static int si4713_choose_econtrol_action(struct si4713_device *sdev, u32 id,
897 case V4L2_CID_RDS_TX_PI: 899 case V4L2_CID_RDS_TX_PI:
898 *property = SI4713_TX_RDS_PI; 900 *property = SI4713_TX_RDS_PI;
899 *mul = 1; 901 *mul = 1;
900 *shadow = &sdev->rds_info.pi;
901 break; 902 break;
902 case V4L2_CID_AUDIO_COMPRESSION_THRESHOLD: 903 case V4L2_CID_AUDIO_COMPRESSION_THRESHOLD:
903 *property = SI4713_TX_ACOMP_THRESHOLD; 904 *property = SI4713_TX_ACOMP_THRESHOLD;
904 *mul = 1; 905 *mul = 1;
905 *shadow = &sdev->acomp_info.threshold;
906 break; 906 break;
907 case V4L2_CID_AUDIO_COMPRESSION_GAIN: 907 case V4L2_CID_AUDIO_COMPRESSION_GAIN:
908 *property = SI4713_TX_ACOMP_GAIN; 908 *property = SI4713_TX_ACOMP_GAIN;
909 *mul = 1; 909 *mul = 1;
910 *shadow = &sdev->acomp_info.gain;
911 break; 910 break;
912 case V4L2_CID_PILOT_TONE_FREQUENCY: 911 case V4L2_CID_PILOT_TONE_FREQUENCY:
913 *property = SI4713_TX_PILOT_FREQUENCY; 912 *property = SI4713_TX_PILOT_FREQUENCY;
914 *mul = 1; 913 *mul = 1;
915 *shadow = &sdev->pilot_info.frequency;
916 break; 914 break;
917 case V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME: 915 case V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME:
918 *property = SI4713_TX_ACOMP_ATTACK_TIME; 916 *property = SI4713_TX_ACOMP_ATTACK_TIME;
919 *mul = ATTACK_TIME_UNIT; 917 *mul = ATTACK_TIME_UNIT;
920 *shadow = &sdev->acomp_info.attack_time;
921 break; 918 break;
922 case V4L2_CID_PILOT_TONE_DEVIATION: 919 case V4L2_CID_PILOT_TONE_DEVIATION:
923 *property = SI4713_TX_PILOT_DEVIATION; 920 *property = SI4713_TX_PILOT_DEVIATION;
924 *mul = 10; 921 *mul = 10;
925 *shadow = &sdev->pilot_info.deviation;
926 break; 922 break;
927 case V4L2_CID_AUDIO_LIMITER_DEVIATION: 923 case V4L2_CID_AUDIO_LIMITER_DEVIATION:
928 *property = SI4713_TX_AUDIO_DEVIATION; 924 *property = SI4713_TX_AUDIO_DEVIATION;
929 *mul = 10; 925 *mul = 10;
930 *shadow = &sdev->limiter_info.deviation;
931 break; 926 break;
932 case V4L2_CID_RDS_TX_DEVIATION: 927 case V4L2_CID_RDS_TX_DEVIATION:
933 *property = SI4713_TX_RDS_DEVIATION; 928 *property = SI4713_TX_RDS_DEVIATION;
934 *mul = 1; 929 *mul = 1;
935 *shadow = &sdev->rds_info.deviation;
936 break; 930 break;
937 931
938 case V4L2_CID_RDS_TX_PTY: 932 case V4L2_CID_RDS_TX_PTY:
939 *property = SI4713_TX_RDS_PS_MISC; 933 *property = SI4713_TX_RDS_PS_MISC;
940 *bit = 5; 934 *bit = 5;
941 *mask = 0x1F << 5; 935 *mask = 0x1F << 5;
942 *shadow = &sdev->rds_info.pty;
943 break; 936 break;
944 case V4L2_CID_AUDIO_LIMITER_ENABLED: 937 case V4L2_CID_AUDIO_LIMITER_ENABLED:
945 *property = SI4713_TX_ACOMP_ENABLE; 938 *property = SI4713_TX_ACOMP_ENABLE;
946 *bit = 1; 939 *bit = 1;
947 *mask = 1 << 1; 940 *mask = 1 << 1;
948 *shadow = &sdev->limiter_info.enabled;
949 break; 941 break;
950 case V4L2_CID_AUDIO_COMPRESSION_ENABLED: 942 case V4L2_CID_AUDIO_COMPRESSION_ENABLED:
951 *property = SI4713_TX_ACOMP_ENABLE; 943 *property = SI4713_TX_ACOMP_ENABLE;
952 *bit = 0; 944 *bit = 0;
953 *mask = 1 << 0; 945 *mask = 1 << 0;
954 *shadow = &sdev->acomp_info.enabled;
955 break; 946 break;
956 case V4L2_CID_PILOT_TONE_ENABLED: 947 case V4L2_CID_PILOT_TONE_ENABLED:
957 *property = SI4713_TX_COMPONENT_ENABLE; 948 *property = SI4713_TX_COMPONENT_ENABLE;
958 *bit = 0; 949 *bit = 0;
959 *mask = 1 << 0; 950 *mask = 1 << 0;
960 *shadow = &sdev->pilot_info.enabled;
961 break; 951 break;
962 952
963 case V4L2_CID_AUDIO_LIMITER_RELEASE_TIME: 953 case V4L2_CID_AUDIO_LIMITER_RELEASE_TIME:
964 *property = SI4713_TX_LIMITER_RELEASE_TIME; 954 *property = SI4713_TX_LIMITER_RELEASE_TIME;
965 *table = limiter_times; 955 *table = limiter_times;
966 *size = ARRAY_SIZE(limiter_times); 956 *size = ARRAY_SIZE(limiter_times);
967 *shadow = &sdev->limiter_info.release_time;
968 break; 957 break;
969 case V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME: 958 case V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME:
970 *property = SI4713_TX_ACOMP_RELEASE_TIME; 959 *property = SI4713_TX_ACOMP_RELEASE_TIME;
971 *table = acomp_rtimes; 960 *table = acomp_rtimes;
972 *size = ARRAY_SIZE(acomp_rtimes); 961 *size = ARRAY_SIZE(acomp_rtimes);
973 *shadow = &sdev->acomp_info.release_time;
974 break; 962 break;
975 case V4L2_CID_TUNE_PREEMPHASIS: 963 case V4L2_CID_TUNE_PREEMPHASIS:
976 *property = SI4713_TX_PREEMPHASIS; 964 *property = SI4713_TX_PREEMPHASIS;
977 *table = preemphasis_values; 965 *table = preemphasis_values;
978 *size = ARRAY_SIZE(preemphasis_values); 966 *size = ARRAY_SIZE(preemphasis_values);
979 *shadow = &sdev->preemphasis;
980 break; 967 break;
981 968
982 default: 969 default:
983 rval = -EINVAL; 970 rval = -EINVAL;
984 }
985
986 return rval;
987}
988
989static int si4713_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc);
990
991/* write string property */
992static int si4713_write_econtrol_string(struct si4713_device *sdev,
993 struct v4l2_ext_control *control)
994{
995 struct v4l2_queryctrl vqc;
996 int len;
997 s32 rval = 0;
998
999 vqc.id = control->id;
1000 rval = si4713_queryctrl(&sdev->sd, &vqc);
1001 if (rval < 0)
1002 goto exit;
1003
1004 switch (control->id) {
1005 case V4L2_CID_RDS_TX_PS_NAME: {
1006 char ps_name[MAX_RDS_PS_NAME + 1];
1007
1008 len = control->size - 1;
1009 if (len < 0 || len > MAX_RDS_PS_NAME) {
1010 rval = -ERANGE;
1011 goto exit;
1012 }
1013 rval = copy_from_user(ps_name, control->string, len);
1014 if (rval) {
1015 rval = -EFAULT;
1016 goto exit;
1017 }
1018 ps_name[len] = '\0';
1019
1020 if (strlen(ps_name) % vqc.step) {
1021 rval = -ERANGE;
1022 goto exit;
1023 }
1024
1025 rval = si4713_set_rds_ps_name(sdev, ps_name);
1026 }
1027 break;
1028
1029 case V4L2_CID_RDS_TX_RADIO_TEXT: {
1030 char radio_text[MAX_RDS_RADIO_TEXT + 1];
1031
1032 len = control->size - 1;
1033 if (len < 0 || len > MAX_RDS_RADIO_TEXT) {
1034 rval = -ERANGE;
1035 goto exit;
1036 }
1037 rval = copy_from_user(radio_text, control->string, len);
1038 if (rval) {
1039 rval = -EFAULT;
1040 goto exit;
1041 }
1042 radio_text[len] = '\0';
1043
1044 if (strlen(radio_text) % vqc.step) {
1045 rval = -ERANGE;
1046 goto exit;
1047 }
1048
1049 rval = si4713_set_rds_radio_text(sdev, radio_text);
1050 }
1051 break;
1052
1053 default:
1054 rval = -EINVAL;
1055 break;
1056 }
1057
1058exit:
1059 return rval;
1060}
1061
1062static int validate_range(struct v4l2_subdev *sd,
1063 struct v4l2_ext_control *control)
1064{
1065 struct v4l2_queryctrl vqc;
1066 int rval;
1067
1068 vqc.id = control->id;
1069 rval = si4713_queryctrl(sd, &vqc);
1070 if (rval < 0)
1071 goto exit;
1072
1073 if (control->value < vqc.minimum || control->value > vqc.maximum)
1074 rval = -ERANGE;
1075
1076exit:
1077 return rval;
1078}
1079
1080/* properties which use tx_tune_power*/
1081static int si4713_write_econtrol_tune(struct si4713_device *sdev,
1082 struct v4l2_ext_control *control)
1083{
1084 s32 rval = 0;
1085 u8 power, antcap;
1086
1087 rval = validate_range(&sdev->sd, control);
1088 if (rval < 0)
1089 return rval;
1090
1091 switch (control->id) {
1092 case V4L2_CID_TUNE_POWER_LEVEL:
1093 power = control->value;
1094 antcap = sdev->antenna_capacitor;
1095 break;
1096 case V4L2_CID_TUNE_ANTENNA_CAPACITOR:
1097 power = sdev->power_level;
1098 antcap = control->value;
1099 break; 971 break;
1100 default:
1101 return -EINVAL;
1102 }
1103
1104 if (sdev->power_state)
1105 rval = si4713_tx_tune_power(sdev, power, antcap);
1106
1107 if (rval == 0) {
1108 sdev->power_level = power;
1109 sdev->antenna_capacitor = antcap;
1110 }
1111
1112 return rval;
1113}
1114
1115static int si4713_write_econtrol_integers(struct si4713_device *sdev,
1116 struct v4l2_ext_control *control)
1117{
1118 s32 rval;
1119 u32 *shadow = NULL, val = 0;
1120 s32 bit = 0, mask = 0;
1121 u16 property = 0;
1122 int mul = 0;
1123 unsigned long *table = NULL;
1124 int size = 0;
1125
1126 rval = validate_range(&sdev->sd, control);
1127 if (rval < 0)
1128 return rval;
1129
1130 rval = si4713_choose_econtrol_action(sdev, control->id, &shadow, &bit,
1131 &mask, &property, &mul, &table, &size);
1132 if (rval < 0)
1133 return rval;
1134
1135 val = control->value;
1136 if (mul) {
1137 val = control->value / mul;
1138 } else if (table) {
1139 rval = usecs_to_dev(control->value, table, size);
1140 if (rval < 0)
1141 return rval;
1142 val = rval;
1143 rval = 0;
1144 }
1145
1146 if (sdev->power_state) {
1147 if (mask) {
1148 rval = si4713_read_property(sdev, property, &val);
1149 if (rval < 0)
1150 return rval;
1151 val = set_bits(val, control->value, bit, mask);
1152 }
1153
1154 rval = si4713_write_property(sdev, property, val);
1155 if (rval < 0)
1156 return rval;
1157 if (mask)
1158 val = control->value;
1159 }
1160
1161 if (mul) {
1162 *shadow = val * mul;
1163 } else if (table) {
1164 rval = dev_to_usecs(val, table, size);
1165 if (rval < 0)
1166 return rval;
1167 *shadow = rval;
1168 rval = 0;
1169 } else {
1170 *shadow = val;
1171 } 972 }
1172 973
1173 return rval; 974 return rval;
@@ -1181,110 +982,25 @@ static int si4713_s_modulator(struct v4l2_subdev *sd, const struct v4l2_modulato
1181 */ 982 */
1182static int si4713_setup(struct si4713_device *sdev) 983static int si4713_setup(struct si4713_device *sdev)
1183{ 984{
1184 struct v4l2_ext_control ctrl;
1185 struct v4l2_frequency f; 985 struct v4l2_frequency f;
1186 struct v4l2_modulator vm; 986 struct v4l2_modulator vm;
1187 struct si4713_device *tmp; 987 int rval;
1188 int rval = 0;
1189
1190 tmp = kmalloc(sizeof(*tmp), GFP_KERNEL);
1191 if (!tmp)
1192 return -ENOMEM;
1193
1194 /* Get a local copy to avoid race */
1195 memcpy(tmp, sdev, sizeof(*sdev));
1196
1197 ctrl.id = V4L2_CID_RDS_TX_PI;
1198 ctrl.value = tmp->rds_info.pi;
1199 rval |= si4713_write_econtrol_integers(sdev, &ctrl);
1200
1201 ctrl.id = V4L2_CID_AUDIO_COMPRESSION_THRESHOLD;
1202 ctrl.value = tmp->acomp_info.threshold;
1203 rval |= si4713_write_econtrol_integers(sdev, &ctrl);
1204
1205 ctrl.id = V4L2_CID_AUDIO_COMPRESSION_GAIN;
1206 ctrl.value = tmp->acomp_info.gain;
1207 rval |= si4713_write_econtrol_integers(sdev, &ctrl);
1208
1209 ctrl.id = V4L2_CID_PILOT_TONE_FREQUENCY;
1210 ctrl.value = tmp->pilot_info.frequency;
1211 rval |= si4713_write_econtrol_integers(sdev, &ctrl);
1212
1213 ctrl.id = V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME;
1214 ctrl.value = tmp->acomp_info.attack_time;
1215 rval |= si4713_write_econtrol_integers(sdev, &ctrl);
1216
1217 ctrl.id = V4L2_CID_PILOT_TONE_DEVIATION;
1218 ctrl.value = tmp->pilot_info.deviation;
1219 rval |= si4713_write_econtrol_integers(sdev, &ctrl);
1220
1221 ctrl.id = V4L2_CID_AUDIO_LIMITER_DEVIATION;
1222 ctrl.value = tmp->limiter_info.deviation;
1223 rval |= si4713_write_econtrol_integers(sdev, &ctrl);
1224
1225 ctrl.id = V4L2_CID_RDS_TX_DEVIATION;
1226 ctrl.value = tmp->rds_info.deviation;
1227 rval |= si4713_write_econtrol_integers(sdev, &ctrl);
1228
1229 ctrl.id = V4L2_CID_RDS_TX_PTY;
1230 ctrl.value = tmp->rds_info.pty;
1231 rval |= si4713_write_econtrol_integers(sdev, &ctrl);
1232
1233 ctrl.id = V4L2_CID_AUDIO_LIMITER_ENABLED;
1234 ctrl.value = tmp->limiter_info.enabled;
1235 rval |= si4713_write_econtrol_integers(sdev, &ctrl);
1236
1237 ctrl.id = V4L2_CID_AUDIO_COMPRESSION_ENABLED;
1238 ctrl.value = tmp->acomp_info.enabled;
1239 rval |= si4713_write_econtrol_integers(sdev, &ctrl);
1240
1241 ctrl.id = V4L2_CID_PILOT_TONE_ENABLED;
1242 ctrl.value = tmp->pilot_info.enabled;
1243 rval |= si4713_write_econtrol_integers(sdev, &ctrl);
1244
1245 ctrl.id = V4L2_CID_AUDIO_LIMITER_RELEASE_TIME;
1246 ctrl.value = tmp->limiter_info.release_time;
1247 rval |= si4713_write_econtrol_integers(sdev, &ctrl);
1248
1249 ctrl.id = V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME;
1250 ctrl.value = tmp->acomp_info.release_time;
1251 rval |= si4713_write_econtrol_integers(sdev, &ctrl);
1252
1253 ctrl.id = V4L2_CID_TUNE_PREEMPHASIS;
1254 ctrl.value = tmp->preemphasis;
1255 rval |= si4713_write_econtrol_integers(sdev, &ctrl);
1256
1257 ctrl.id = V4L2_CID_RDS_TX_PS_NAME;
1258 rval |= si4713_set_rds_ps_name(sdev, tmp->rds_info.ps_name);
1259
1260 ctrl.id = V4L2_CID_RDS_TX_RADIO_TEXT;
1261 rval |= si4713_set_rds_radio_text(sdev, tmp->rds_info.radio_text);
1262 988
1263 /* Device procedure needs to set frequency first */ 989 /* Device procedure needs to set frequency first */
1264 f.tuner = 0; 990 f.tuner = 0;
1265 f.frequency = tmp->frequency ? tmp->frequency : DEFAULT_FREQUENCY; 991 f.frequency = sdev->frequency ? sdev->frequency : DEFAULT_FREQUENCY;
1266 f.frequency = si4713_to_v4l2(f.frequency); 992 f.frequency = si4713_to_v4l2(f.frequency);
1267 rval |= si4713_s_frequency(&sdev->sd, &f); 993 rval = si4713_s_frequency(&sdev->sd, &f);
1268
1269 ctrl.id = V4L2_CID_TUNE_POWER_LEVEL;
1270 ctrl.value = tmp->power_level;
1271 rval |= si4713_write_econtrol_tune(sdev, &ctrl);
1272
1273 ctrl.id = V4L2_CID_TUNE_ANTENNA_CAPACITOR;
1274 ctrl.value = tmp->antenna_capacitor;
1275 rval |= si4713_write_econtrol_tune(sdev, &ctrl);
1276 994
1277 vm.index = 0; 995 vm.index = 0;
1278 if (tmp->stereo) 996 if (sdev->stereo)
1279 vm.txsubchans = V4L2_TUNER_SUB_STEREO; 997 vm.txsubchans = V4L2_TUNER_SUB_STEREO;
1280 else 998 else
1281 vm.txsubchans = V4L2_TUNER_SUB_MONO; 999 vm.txsubchans = V4L2_TUNER_SUB_MONO;
1282 if (tmp->rds_info.enabled) 1000 if (sdev->rds_enabled)
1283 vm.txsubchans |= V4L2_TUNER_SUB_RDS; 1001 vm.txsubchans |= V4L2_TUNER_SUB_RDS;
1284 si4713_s_modulator(&sdev->sd, &vm); 1002 si4713_s_modulator(&sdev->sd, &vm);
1285 1003
1286 kfree(tmp);
1287
1288 return rval; 1004 return rval;
1289} 1005}
1290 1006
@@ -1308,406 +1024,116 @@ static int si4713_initialize(struct si4713_device *sdev)
1308 if (rval < 0) 1024 if (rval < 0)
1309 return rval; 1025 return rval;
1310 1026
1311 sdev->rds_info.pi = DEFAULT_RDS_PI;
1312 sdev->rds_info.pty = DEFAULT_RDS_PTY;
1313 sdev->rds_info.deviation = DEFAULT_RDS_DEVIATION;
1314 strlcpy(sdev->rds_info.ps_name, DEFAULT_RDS_PS_NAME, MAX_RDS_PS_NAME);
1315 strlcpy(sdev->rds_info.radio_text, DEFAULT_RDS_RADIO_TEXT,
1316 MAX_RDS_RADIO_TEXT);
1317 sdev->rds_info.enabled = 1;
1318
1319 sdev->limiter_info.release_time = DEFAULT_LIMITER_RTIME;
1320 sdev->limiter_info.deviation = DEFAULT_LIMITER_DEV;
1321 sdev->limiter_info.enabled = 1;
1322
1323 sdev->pilot_info.deviation = DEFAULT_PILOT_DEVIATION;
1324 sdev->pilot_info.frequency = DEFAULT_PILOT_FREQUENCY;
1325 sdev->pilot_info.enabled = 1;
1326
1327 sdev->acomp_info.release_time = DEFAULT_ACOMP_RTIME;
1328 sdev->acomp_info.attack_time = DEFAULT_ACOMP_ATIME;
1329 sdev->acomp_info.threshold = DEFAULT_ACOMP_THRESHOLD;
1330 sdev->acomp_info.gain = DEFAULT_ACOMP_GAIN;
1331 sdev->acomp_info.enabled = 1;
1332 1027
1333 sdev->frequency = DEFAULT_FREQUENCY; 1028 sdev->frequency = DEFAULT_FREQUENCY;
1334 sdev->preemphasis = DEFAULT_PREEMPHASIS;
1335 sdev->mute = DEFAULT_MUTE;
1336 sdev->power_level = DEFAULT_POWER_LEVEL;
1337 sdev->antenna_capacitor = 0;
1338 sdev->stereo = 1; 1029 sdev->stereo = 1;
1339 sdev->tune_rnl = DEFAULT_TUNE_RNL; 1030 sdev->tune_rnl = DEFAULT_TUNE_RNL;
1340 1031 return 0;
1341 return rval;
1342}
1343
1344/* read string property */
1345static int si4713_read_econtrol_string(struct si4713_device *sdev,
1346 struct v4l2_ext_control *control)
1347{
1348 s32 rval = 0;
1349
1350 switch (control->id) {
1351 case V4L2_CID_RDS_TX_PS_NAME:
1352 if (strlen(sdev->rds_info.ps_name) + 1 > control->size) {
1353 control->size = MAX_RDS_PS_NAME + 1;
1354 rval = -ENOSPC;
1355 goto exit;
1356 }
1357 rval = copy_to_user(control->string, sdev->rds_info.ps_name,
1358 strlen(sdev->rds_info.ps_name) + 1);
1359 if (rval)
1360 rval = -EFAULT;
1361 break;
1362
1363 case V4L2_CID_RDS_TX_RADIO_TEXT:
1364 if (strlen(sdev->rds_info.radio_text) + 1 > control->size) {
1365 control->size = MAX_RDS_RADIO_TEXT + 1;
1366 rval = -ENOSPC;
1367 goto exit;
1368 }
1369 rval = copy_to_user(control->string, sdev->rds_info.radio_text,
1370 strlen(sdev->rds_info.radio_text) + 1);
1371 if (rval)
1372 rval = -EFAULT;
1373 break;
1374
1375 default:
1376 rval = -EINVAL;
1377 break;
1378 }
1379
1380exit:
1381 return rval;
1382}
1383
1384/*
1385 * si4713_update_tune_status - update properties from tx_tune_status
1386 * command.
1387 * @sdev: si4713_device structure for the device we are communicating
1388 */
1389static int si4713_update_tune_status(struct si4713_device *sdev)
1390{
1391 int rval;
1392 u16 f = 0;
1393 u8 p = 0, a = 0, n = 0;
1394
1395 rval = si4713_tx_tune_status(sdev, 0x00, &f, &p, &a, &n);
1396
1397 if (rval < 0)
1398 goto exit;
1399
1400 sdev->power_level = p;
1401 sdev->antenna_capacitor = a;
1402 sdev->tune_rnl = n;
1403
1404exit:
1405 return rval;
1406}
1407
1408/* properties which use tx_tune_status */
1409static int si4713_read_econtrol_tune(struct si4713_device *sdev,
1410 struct v4l2_ext_control *control)
1411{
1412 s32 rval = 0;
1413
1414 if (sdev->power_state) {
1415 rval = si4713_update_tune_status(sdev);
1416 if (rval < 0)
1417 return rval;
1418 }
1419
1420 switch (control->id) {
1421 case V4L2_CID_TUNE_POWER_LEVEL:
1422 control->value = sdev->power_level;
1423 break;
1424 case V4L2_CID_TUNE_ANTENNA_CAPACITOR:
1425 control->value = sdev->antenna_capacitor;
1426 break;
1427 default:
1428 return -EINVAL;
1429 }
1430
1431 return rval;
1432} 1032}
1433 1033
1434static int si4713_read_econtrol_integers(struct si4713_device *sdev, 1034/* si4713_s_ctrl - set the value of a control */
1435 struct v4l2_ext_control *control) 1035static int si4713_s_ctrl(struct v4l2_ctrl *ctrl)
1436{ 1036{
1437 s32 rval; 1037 struct si4713_device *sdev =
1438 u32 *shadow = NULL, val = 0; 1038 container_of(ctrl->handler, struct si4713_device, ctrl_handler);
1039 u32 val = 0;
1439 s32 bit = 0, mask = 0; 1040 s32 bit = 0, mask = 0;
1440 u16 property = 0; 1041 u16 property = 0;
1441 int mul = 0; 1042 int mul = 0;
1442 unsigned long *table = NULL; 1043 unsigned long *table = NULL;
1443 int size = 0; 1044 int size = 0;
1045 bool force = false;
1046 int c;
1047 int ret = 0;
1444 1048
1445 rval = si4713_choose_econtrol_action(sdev, control->id, &shadow, &bit, 1049 if (ctrl->id != V4L2_CID_AUDIO_MUTE)
1446 &mask, &property, &mul, &table, &size);
1447 if (rval < 0)
1448 return rval;
1449
1450 if (sdev->power_state) {
1451 rval = si4713_read_property(sdev, property, &val);
1452 if (rval < 0)
1453 return rval;
1454
1455 /* Keep negative values for threshold */
1456 if (control->id == V4L2_CID_AUDIO_COMPRESSION_THRESHOLD)
1457 *shadow = (s16)val;
1458 else if (mask)
1459 *shadow = get_status_bit(val, bit, mask);
1460 else if (mul)
1461 *shadow = val * mul;
1462 else
1463 *shadow = dev_to_usecs(val, table, size);
1464 }
1465
1466 control->value = *shadow;
1467
1468 return rval;
1469}
1470
1471/*
1472 * Video4Linux Subdev Interface
1473 */
1474/* si4713_s_ext_ctrls - set extended controls value */
1475static int si4713_s_ext_ctrls(struct v4l2_subdev *sd,
1476 struct v4l2_ext_controls *ctrls)
1477{
1478 struct si4713_device *sdev = to_si4713_device(sd);
1479 int i;
1480
1481 if (ctrls->ctrl_class != V4L2_CTRL_CLASS_FM_TX)
1482 return -EINVAL; 1050 return -EINVAL;
1483 1051 if (ctrl->is_new) {
1484 for (i = 0; i < ctrls->count; i++) { 1052 if (ctrl->val) {
1485 int err; 1053 ret = si4713_set_mute(sdev, ctrl->val);
1486 1054 if (!ret)
1487 switch ((ctrls->controls + i)->id) { 1055 ret = si4713_set_power_state(sdev, POWER_DOWN);
1488 case V4L2_CID_RDS_TX_PS_NAME: 1056 return ret;
1489 case V4L2_CID_RDS_TX_RADIO_TEXT:
1490 err = si4713_write_econtrol_string(sdev,
1491 ctrls->controls + i);
1492 break;
1493 case V4L2_CID_TUNE_ANTENNA_CAPACITOR:
1494 case V4L2_CID_TUNE_POWER_LEVEL:
1495 err = si4713_write_econtrol_tune(sdev,
1496 ctrls->controls + i);
1497 break;
1498 default:
1499 err = si4713_write_econtrol_integers(sdev,
1500 ctrls->controls + i);
1501 }
1502
1503 if (err < 0) {
1504 ctrls->error_idx = i;
1505 return err;
1506 } 1057 }
1058 ret = si4713_set_power_state(sdev, POWER_UP);
1059 if (!ret)
1060 ret = si4713_set_mute(sdev, ctrl->val);
1061 if (!ret)
1062 ret = si4713_setup(sdev);
1063 if (ret)
1064 return ret;
1065 force = true;
1507 } 1066 }
1508 1067
1509 return 0; 1068 if (!sdev->power_state)
1510} 1069 return 0;
1511
1512/* si4713_g_ext_ctrls - get extended controls value */
1513static int si4713_g_ext_ctrls(struct v4l2_subdev *sd,
1514 struct v4l2_ext_controls *ctrls)
1515{
1516 struct si4713_device *sdev = to_si4713_device(sd);
1517 int i;
1518 1070
1519 if (ctrls->ctrl_class != V4L2_CTRL_CLASS_FM_TX) 1071 for (c = 1; !ret && c < ctrl->ncontrols; c++) {
1520 return -EINVAL; 1072 ctrl = ctrl->cluster[c];
1521 1073
1522 for (i = 0; i < ctrls->count; i++) { 1074 if (!force && !ctrl->is_new)
1523 int err; 1075 continue;
1524 1076
1525 switch ((ctrls->controls + i)->id) { 1077 switch (ctrl->id) {
1526 case V4L2_CID_RDS_TX_PS_NAME: 1078 case V4L2_CID_RDS_TX_PS_NAME:
1079 ret = si4713_set_rds_ps_name(sdev, ctrl->string);
1080 break;
1081
1527 case V4L2_CID_RDS_TX_RADIO_TEXT: 1082 case V4L2_CID_RDS_TX_RADIO_TEXT:
1528 err = si4713_read_econtrol_string(sdev, 1083 ret = si4713_set_rds_radio_text(sdev, ctrl->string);
1529 ctrls->controls + i);
1530 break; 1084 break;
1085
1531 case V4L2_CID_TUNE_ANTENNA_CAPACITOR: 1086 case V4L2_CID_TUNE_ANTENNA_CAPACITOR:
1087 /* don't handle this control if we force setting all
1088 * controls since in that case it will be handled by
1089 * V4L2_CID_TUNE_POWER_LEVEL. */
1090 if (force)
1091 break;
1092 /* fall through */
1532 case V4L2_CID_TUNE_POWER_LEVEL: 1093 case V4L2_CID_TUNE_POWER_LEVEL:
1533 err = si4713_read_econtrol_tune(sdev, 1094 ret = si4713_tx_tune_power(sdev,
1534 ctrls->controls + i); 1095 sdev->tune_pwr_level->val, sdev->tune_ant_cap->val);
1096 if (!ret) {
1097 /* Make sure we don't set this twice */
1098 sdev->tune_ant_cap->is_new = false;
1099 sdev->tune_pwr_level->is_new = false;
1100 }
1535 break; 1101 break;
1536 default:
1537 err = si4713_read_econtrol_integers(sdev,
1538 ctrls->controls + i);
1539 }
1540
1541 if (err < 0) {
1542 ctrls->error_idx = i;
1543 return err;
1544 }
1545 }
1546
1547 return 0;
1548}
1549
1550/* si4713_queryctrl - enumerate control items */
1551static int si4713_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
1552{
1553 int rval = 0;
1554
1555 switch (qc->id) {
1556 /* User class controls */
1557 case V4L2_CID_AUDIO_MUTE:
1558 rval = v4l2_ctrl_query_fill(qc, 0, 1, 1, DEFAULT_MUTE);
1559 break;
1560 /* FM_TX class controls */
1561 case V4L2_CID_RDS_TX_PI:
1562 rval = v4l2_ctrl_query_fill(qc, 0, 0xFFFF, 1, DEFAULT_RDS_PI);
1563 break;
1564 case V4L2_CID_RDS_TX_PTY:
1565 rval = v4l2_ctrl_query_fill(qc, 0, 31, 1, DEFAULT_RDS_PTY);
1566 break;
1567 case V4L2_CID_RDS_TX_DEVIATION:
1568 rval = v4l2_ctrl_query_fill(qc, 0, MAX_RDS_DEVIATION,
1569 10, DEFAULT_RDS_DEVIATION);
1570 break;
1571 case V4L2_CID_RDS_TX_PS_NAME:
1572 /*
1573 * Report step as 8. From RDS spec, psname
1574 * should be 8. But there are receivers which scroll strings
1575 * sized as 8xN.
1576 */
1577 rval = v4l2_ctrl_query_fill(qc, 0, MAX_RDS_PS_NAME, 8, 0);
1578 break;
1579 case V4L2_CID_RDS_TX_RADIO_TEXT:
1580 /*
1581 * Report step as 32 (2A block). From RDS spec,
1582 * radio text should be 32 for 2A block. But there are receivers
1583 * which scroll strings sized as 32xN. Setting default to 32.
1584 */
1585 rval = v4l2_ctrl_query_fill(qc, 0, MAX_RDS_RADIO_TEXT, 32, 0);
1586 break;
1587 1102
1588 case V4L2_CID_AUDIO_LIMITER_ENABLED: 1103 default:
1589 rval = v4l2_ctrl_query_fill(qc, 0, 1, 1, 1); 1104 ret = si4713_choose_econtrol_action(sdev, ctrl->id, &bit,
1590 break; 1105 &mask, &property, &mul, &table, &size);
1591 case V4L2_CID_AUDIO_LIMITER_RELEASE_TIME: 1106 if (ret < 0)
1592 rval = v4l2_ctrl_query_fill(qc, 250, MAX_LIMITER_RELEASE_TIME, 1107 break;
1593 50, DEFAULT_LIMITER_RTIME); 1108
1594 break; 1109 val = ctrl->val;
1595 case V4L2_CID_AUDIO_LIMITER_DEVIATION: 1110 if (mul) {
1596 rval = v4l2_ctrl_query_fill(qc, 0, MAX_LIMITER_DEVIATION, 1111 val = val / mul;
1597 10, DEFAULT_LIMITER_DEV); 1112 } else if (table) {
1598 break; 1113 ret = usecs_to_dev(val, table, size);
1599 1114 if (ret < 0)
1600 case V4L2_CID_AUDIO_COMPRESSION_ENABLED: 1115 break;
1601 rval = v4l2_ctrl_query_fill(qc, 0, 1, 1, 1); 1116 val = ret;
1602 break; 1117 ret = 0;
1603 case V4L2_CID_AUDIO_COMPRESSION_GAIN: 1118 }
1604 rval = v4l2_ctrl_query_fill(qc, 0, MAX_ACOMP_GAIN, 1,
1605 DEFAULT_ACOMP_GAIN);
1606 break;
1607 case V4L2_CID_AUDIO_COMPRESSION_THRESHOLD:
1608 rval = v4l2_ctrl_query_fill(qc, MIN_ACOMP_THRESHOLD,
1609 MAX_ACOMP_THRESHOLD, 1,
1610 DEFAULT_ACOMP_THRESHOLD);
1611 break;
1612 case V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME:
1613 rval = v4l2_ctrl_query_fill(qc, 0, MAX_ACOMP_ATTACK_TIME,
1614 500, DEFAULT_ACOMP_ATIME);
1615 break;
1616 case V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME:
1617 rval = v4l2_ctrl_query_fill(qc, 100000, MAX_ACOMP_RELEASE_TIME,
1618 100000, DEFAULT_ACOMP_RTIME);
1619 break;
1620
1621 case V4L2_CID_PILOT_TONE_ENABLED:
1622 rval = v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
1623 break;
1624 case V4L2_CID_PILOT_TONE_DEVIATION:
1625 rval = v4l2_ctrl_query_fill(qc, 0, MAX_PILOT_DEVIATION,
1626 10, DEFAULT_PILOT_DEVIATION);
1627 break;
1628 case V4L2_CID_PILOT_TONE_FREQUENCY:
1629 rval = v4l2_ctrl_query_fill(qc, 0, MAX_PILOT_FREQUENCY,
1630 1, DEFAULT_PILOT_FREQUENCY);
1631 break;
1632
1633 case V4L2_CID_TUNE_PREEMPHASIS:
1634 rval = v4l2_ctrl_query_fill(qc, V4L2_PREEMPHASIS_DISABLED,
1635 V4L2_PREEMPHASIS_75_uS, 1,
1636 V4L2_PREEMPHASIS_50_uS);
1637 break;
1638 case V4L2_CID_TUNE_POWER_LEVEL:
1639 rval = v4l2_ctrl_query_fill(qc, 0, 120, 1, DEFAULT_POWER_LEVEL);
1640 break;
1641 case V4L2_CID_TUNE_ANTENNA_CAPACITOR:
1642 rval = v4l2_ctrl_query_fill(qc, 0, 191, 1, 0);
1643 break;
1644 default:
1645 rval = -EINVAL;
1646 break;
1647 }
1648
1649 return rval;
1650}
1651
1652/* si4713_g_ctrl - get the value of a control */
1653static int si4713_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
1654{
1655 struct si4713_device *sdev = to_si4713_device(sd);
1656 int rval = 0;
1657
1658 if (!sdev)
1659 return -ENODEV;
1660
1661 if (sdev->power_state) {
1662 rval = si4713_read_property(sdev, SI4713_TX_LINE_INPUT_MUTE,
1663 &sdev->mute);
1664
1665 if (rval < 0)
1666 return rval;
1667 }
1668
1669 switch (ctrl->id) {
1670 case V4L2_CID_AUDIO_MUTE:
1671 ctrl->value = get_mute(sdev->mute);
1672 break;
1673 }
1674
1675 return rval;
1676}
1677
1678/* si4713_s_ctrl - set the value of a control */
1679static int si4713_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
1680{
1681 struct si4713_device *sdev = to_si4713_device(sd);
1682 int rval = 0;
1683
1684 if (!sdev)
1685 return -ENODEV;
1686
1687 switch (ctrl->id) {
1688 case V4L2_CID_AUDIO_MUTE:
1689 if (ctrl->value) {
1690 rval = si4713_set_mute(sdev, ctrl->value);
1691 if (rval < 0)
1692 goto exit;
1693
1694 rval = si4713_set_power_state(sdev, POWER_DOWN);
1695 } else {
1696 rval = si4713_set_power_state(sdev, POWER_UP);
1697 if (rval < 0)
1698 goto exit;
1699 1119
1700 rval = si4713_setup(sdev); 1120 if (mask) {
1701 if (rval < 0) 1121 ret = si4713_read_property(sdev, property, &val);
1702 goto exit; 1122 if (ret < 0)
1123 break;
1124 val = set_bits(val, ctrl->val, bit, mask);
1125 }
1703 1126
1704 rval = si4713_set_mute(sdev, ctrl->value); 1127 ret = si4713_write_property(sdev, property, val);
1128 if (ret < 0)
1129 break;
1130 if (mask)
1131 val = ctrl->val;
1132 break;
1705 } 1133 }
1706 break;
1707 } 1134 }
1708 1135
1709exit: 1136 return ret;
1710 return rval;
1711} 1137}
1712 1138
1713/* si4713_ioctl - deal with private ioctls (only rnl for now) */ 1139/* si4713_ioctl - deal with private ioctls (only rnl for now) */
@@ -1746,15 +1172,6 @@ static long si4713_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
1746 return rval; 1172 return rval;
1747} 1173}
1748 1174
1749static const struct v4l2_subdev_core_ops si4713_subdev_core_ops = {
1750 .queryctrl = si4713_queryctrl,
1751 .g_ext_ctrls = si4713_g_ext_ctrls,
1752 .s_ext_ctrls = si4713_s_ext_ctrls,
1753 .g_ctrl = si4713_g_ctrl,
1754 .s_ctrl = si4713_s_ctrl,
1755 .ioctl = si4713_ioctl,
1756};
1757
1758/* si4713_g_modulator - get modulator attributes */ 1175/* si4713_g_modulator - get modulator attributes */
1759static int si4713_g_modulator(struct v4l2_subdev *sd, struct v4l2_modulator *vm) 1176static int si4713_g_modulator(struct v4l2_subdev *sd, struct v4l2_modulator *vm)
1760{ 1177{
@@ -1784,7 +1201,6 @@ static int si4713_g_modulator(struct v4l2_subdev *sd, struct v4l2_modulator *vm)
1784 return rval; 1201 return rval;
1785 1202
1786 sdev->stereo = get_status_bit(comp_en, 1, 1 << 1); 1203 sdev->stereo = get_status_bit(comp_en, 1, 1 << 1);
1787 sdev->rds_info.enabled = get_status_bit(comp_en, 2, 1 << 2);
1788 } 1204 }
1789 1205
1790 /* Report current audio mode: mono or stereo */ 1206 /* Report current audio mode: mono or stereo */
@@ -1794,7 +1210,7 @@ static int si4713_g_modulator(struct v4l2_subdev *sd, struct v4l2_modulator *vm)
1794 vm->txsubchans = V4L2_TUNER_SUB_MONO; 1210 vm->txsubchans = V4L2_TUNER_SUB_MONO;
1795 1211
1796 /* Report rds feature status */ 1212 /* Report rds feature status */
1797 if (sdev->rds_info.enabled) 1213 if (sdev->rds_enabled)
1798 vm->txsubchans |= V4L2_TUNER_SUB_RDS; 1214 vm->txsubchans |= V4L2_TUNER_SUB_RDS;
1799 else 1215 else
1800 vm->txsubchans &= ~V4L2_TUNER_SUB_RDS; 1216 vm->txsubchans &= ~V4L2_TUNER_SUB_RDS;
@@ -1842,7 +1258,7 @@ static int si4713_s_modulator(struct v4l2_subdev *sd, const struct v4l2_modulato
1842 } 1258 }
1843 1259
1844 sdev->stereo = stereo; 1260 sdev->stereo = stereo;
1845 sdev->rds_info.enabled = rds; 1261 sdev->rds_enabled = rds;
1846 1262
1847 return rval; 1263 return rval;
1848} 1264}
@@ -1897,6 +1313,14 @@ static int si4713_s_frequency(struct v4l2_subdev *sd, const struct v4l2_frequenc
1897 return rval; 1313 return rval;
1898} 1314}
1899 1315
1316static const struct v4l2_ctrl_ops si4713_ctrl_ops = {
1317 .s_ctrl = si4713_s_ctrl,
1318};
1319
1320static const struct v4l2_subdev_core_ops si4713_subdev_core_ops = {
1321 .ioctl = si4713_ioctl,
1322};
1323
1900static const struct v4l2_subdev_tuner_ops si4713_subdev_tuner_ops = { 1324static const struct v4l2_subdev_tuner_ops si4713_subdev_tuner_ops = {
1901 .g_frequency = si4713_g_frequency, 1325 .g_frequency = si4713_g_frequency,
1902 .s_frequency = si4713_s_frequency, 1326 .s_frequency = si4713_s_frequency,
@@ -1918,6 +1342,7 @@ static int si4713_probe(struct i2c_client *client,
1918{ 1342{
1919 struct si4713_device *sdev; 1343 struct si4713_device *sdev;
1920 struct si4713_platform_data *pdata = client->dev.platform_data; 1344 struct si4713_platform_data *pdata = client->dev.platform_data;
1345 struct v4l2_ctrl_handler *hdl;
1921 int rval, i; 1346 int rval, i;
1922 1347
1923 sdev = kzalloc(sizeof *sdev, GFP_KERNEL); 1348 sdev = kzalloc(sizeof *sdev, GFP_KERNEL);
@@ -1953,6 +1378,82 @@ static int si4713_probe(struct i2c_client *client,
1953 1378
1954 init_completion(&sdev->work); 1379 init_completion(&sdev->work);
1955 1380
1381 hdl = &sdev->ctrl_handler;
1382 v4l2_ctrl_handler_init(hdl, 20);
1383 sdev->mute = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
1384 V4L2_CID_AUDIO_MUTE, 0, 1, 1, DEFAULT_MUTE);
1385
1386 sdev->rds_pi = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
1387 V4L2_CID_RDS_TX_PI, 0, 0xffff, 1, DEFAULT_RDS_PI);
1388 sdev->rds_pty = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
1389 V4L2_CID_RDS_TX_PTY, 0, 31, 1, DEFAULT_RDS_PTY);
1390 sdev->rds_deviation = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
1391 V4L2_CID_RDS_TX_DEVIATION, 0, MAX_RDS_DEVIATION,
1392 10, DEFAULT_RDS_DEVIATION);
1393 /*
1394 * Report step as 8. From RDS spec, psname
1395 * should be 8. But there are receivers which scroll strings
1396 * sized as 8xN.
1397 */
1398 sdev->rds_ps_name = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
1399 V4L2_CID_RDS_TX_PS_NAME, 0, MAX_RDS_PS_NAME, 8, 0);
1400 /*
1401 * Report step as 32 (2A block). From RDS spec,
1402 * radio text should be 32 for 2A block. But there are receivers
1403 * which scroll strings sized as 32xN. Setting default to 32.
1404 */
1405 sdev->rds_radio_text = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
1406 V4L2_CID_RDS_TX_RADIO_TEXT, 0, MAX_RDS_RADIO_TEXT, 32, 0);
1407
1408 sdev->limiter_enabled = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
1409 V4L2_CID_AUDIO_LIMITER_ENABLED, 0, 1, 1, 1);
1410 sdev->limiter_release_time = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
1411 V4L2_CID_AUDIO_LIMITER_RELEASE_TIME, 250,
1412 MAX_LIMITER_RELEASE_TIME, 10, DEFAULT_LIMITER_RTIME);
1413 sdev->limiter_deviation = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
1414 V4L2_CID_AUDIO_LIMITER_DEVIATION, 0,
1415 MAX_LIMITER_DEVIATION, 10, DEFAULT_LIMITER_DEV);
1416
1417 sdev->compression_enabled = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
1418 V4L2_CID_AUDIO_COMPRESSION_ENABLED, 0, 1, 1, 1);
1419 sdev->compression_gain = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
1420 V4L2_CID_AUDIO_COMPRESSION_GAIN, 0, MAX_ACOMP_GAIN, 1,
1421 DEFAULT_ACOMP_GAIN);
1422 sdev->compression_threshold = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
1423 V4L2_CID_AUDIO_COMPRESSION_THRESHOLD, MIN_ACOMP_THRESHOLD,
1424 MAX_ACOMP_THRESHOLD, 1,
1425 DEFAULT_ACOMP_THRESHOLD);
1426 sdev->compression_attack_time = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
1427 V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME, 0,
1428 MAX_ACOMP_ATTACK_TIME, 500, DEFAULT_ACOMP_ATIME);
1429 sdev->compression_release_time = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
1430 V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME, 100000,
1431 MAX_ACOMP_RELEASE_TIME, 100000, DEFAULT_ACOMP_RTIME);
1432
1433 sdev->pilot_tone_enabled = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
1434 V4L2_CID_PILOT_TONE_ENABLED, 0, 1, 1, 1);
1435 sdev->pilot_tone_deviation = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
1436 V4L2_CID_PILOT_TONE_DEVIATION, 0, MAX_PILOT_DEVIATION,
1437 10, DEFAULT_PILOT_DEVIATION);
1438 sdev->pilot_tone_freq = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
1439 V4L2_CID_PILOT_TONE_FREQUENCY, 0, MAX_PILOT_FREQUENCY,
1440 1, DEFAULT_PILOT_FREQUENCY);
1441
1442 sdev->tune_preemphasis = v4l2_ctrl_new_std_menu(hdl, &si4713_ctrl_ops,
1443 V4L2_CID_TUNE_PREEMPHASIS,
1444 V4L2_PREEMPHASIS_75_uS, 0, V4L2_PREEMPHASIS_50_uS);
1445 sdev->tune_pwr_level = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
1446 V4L2_CID_TUNE_POWER_LEVEL, 0, 120, 1, DEFAULT_POWER_LEVEL);
1447 sdev->tune_ant_cap = v4l2_ctrl_new_std(hdl, &si4713_ctrl_ops,
1448 V4L2_CID_TUNE_ANTENNA_CAPACITOR, 0, 191, 1, 0);
1449
1450 if (hdl->error) {
1451 rval = hdl->error;
1452 goto free_ctrls;
1453 }
1454 v4l2_ctrl_cluster(20, &sdev->mute);
1455 sdev->sd.ctrl_handler = hdl;
1456
1956 if (client->irq) { 1457 if (client->irq) {
1957 rval = request_irq(client->irq, 1458 rval = request_irq(client->irq,
1958 si4713_handler, IRQF_TRIGGER_FALLING | IRQF_DISABLED, 1459 si4713_handler, IRQF_TRIGGER_FALLING | IRQF_DISABLED,
@@ -1977,6 +1478,8 @@ static int si4713_probe(struct i2c_client *client,
1977free_irq: 1478free_irq:
1978 if (client->irq) 1479 if (client->irq)
1979 free_irq(client->irq, sdev); 1480 free_irq(client->irq, sdev);
1481free_ctrls:
1482 v4l2_ctrl_handler_free(hdl);
1980put_reg: 1483put_reg:
1981 regulator_bulk_free(ARRAY_SIZE(sdev->supplies), sdev->supplies); 1484 regulator_bulk_free(ARRAY_SIZE(sdev->supplies), sdev->supplies);
1982free_gpio: 1485free_gpio:
@@ -2001,6 +1504,7 @@ static int si4713_remove(struct i2c_client *client)
2001 free_irq(client->irq, sdev); 1504 free_irq(client->irq, sdev);
2002 1505
2003 v4l2_device_unregister_subdev(sd); 1506 v4l2_device_unregister_subdev(sd);
1507 v4l2_ctrl_handler_free(sd->ctrl_handler);
2004 regulator_bulk_free(ARRAY_SIZE(sdev->supplies), sdev->supplies); 1508 regulator_bulk_free(ARRAY_SIZE(sdev->supplies), sdev->supplies);
2005 if (gpio_is_valid(sdev->gpio_reset)) 1509 if (gpio_is_valid(sdev->gpio_reset))
2006 gpio_free(sdev->gpio_reset); 1510 gpio_free(sdev->gpio_reset);
diff --git a/drivers/media/radio/si4713-i2c.h b/drivers/media/radio/si4713-i2c.h
index 979828da9d27..25cdea26343b 100644
--- a/drivers/media/radio/si4713-i2c.h
+++ b/drivers/media/radio/si4713-i2c.h
@@ -16,6 +16,7 @@
16#define SI4713_I2C_H 16#define SI4713_I2C_H
17 17
18#include <media/v4l2-subdev.h> 18#include <media/v4l2-subdev.h>
19#include <media/v4l2-ctrls.h>
19#include <media/si4713.h> 20#include <media/si4713.h>
20 21
21#define SI4713_PRODUCT_NUMBER 0x0D 22#define SI4713_PRODUCT_NUMBER 0x0D
@@ -160,56 +161,33 @@
160#define POWER_UP 0x01 161#define POWER_UP 0x01
161#define POWER_DOWN 0x00 162#define POWER_DOWN 0x00
162 163
163struct rds_info {
164 u32 pi;
165#define MAX_RDS_PTY 31 164#define MAX_RDS_PTY 31
166 u32 pty;
167#define MAX_RDS_DEVIATION 90000 165#define MAX_RDS_DEVIATION 90000
168 u32 deviation; 166
169/* 167/*
170 * PSNAME is known to be defined as 8 character sized (RDS Spec). 168 * PSNAME is known to be defined as 8 character sized (RDS Spec).
171 * However, there is receivers which scroll PSNAME 8xN sized. 169 * However, there is receivers which scroll PSNAME 8xN sized.
172 */ 170 */
173#define MAX_RDS_PS_NAME 96 171#define MAX_RDS_PS_NAME 96
174 u8 ps_name[MAX_RDS_PS_NAME + 1]; 172
175/* 173/*
176 * MAX_RDS_RADIO_TEXT is known to be defined as 32 (2A group) or 64 (2B group) 174 * MAX_RDS_RADIO_TEXT is known to be defined as 32 (2A group) or 64 (2B group)
177 * character sized (RDS Spec). 175 * character sized (RDS Spec).
178 * However, there is receivers which scroll them as well. 176 * However, there is receivers which scroll them as well.
179 */ 177 */
180#define MAX_RDS_RADIO_TEXT 384 178#define MAX_RDS_RADIO_TEXT 384
181 u8 radio_text[MAX_RDS_RADIO_TEXT + 1];
182 u32 enabled;
183};
184 179
185struct limiter_info {
186#define MAX_LIMITER_RELEASE_TIME 102390 180#define MAX_LIMITER_RELEASE_TIME 102390
187 u32 release_time;
188#define MAX_LIMITER_DEVIATION 90000 181#define MAX_LIMITER_DEVIATION 90000
189 u32 deviation;
190 u32 enabled;
191};
192 182
193struct pilot_info {
194#define MAX_PILOT_DEVIATION 90000 183#define MAX_PILOT_DEVIATION 90000
195 u32 deviation;
196#define MAX_PILOT_FREQUENCY 19000 184#define MAX_PILOT_FREQUENCY 19000
197 u32 frequency;
198 u32 enabled;
199};
200 185
201struct acomp_info {
202#define MAX_ACOMP_RELEASE_TIME 1000000 186#define MAX_ACOMP_RELEASE_TIME 1000000
203 u32 release_time;
204#define MAX_ACOMP_ATTACK_TIME 5000 187#define MAX_ACOMP_ATTACK_TIME 5000
205 u32 attack_time;
206#define MAX_ACOMP_THRESHOLD 0 188#define MAX_ACOMP_THRESHOLD 0
207#define MIN_ACOMP_THRESHOLD (-40) 189#define MIN_ACOMP_THRESHOLD (-40)
208 s32 threshold;
209#define MAX_ACOMP_GAIN 20 190#define MAX_ACOMP_GAIN 20
210 u32 gain;
211 u32 enabled;
212};
213 191
214#define SI4713_NUM_SUPPLIES 2 192#define SI4713_NUM_SUPPLIES 2
215 193
@@ -219,20 +197,41 @@ struct acomp_info {
219struct si4713_device { 197struct si4713_device {
220 /* v4l2_subdev and i2c reference (v4l2_subdev priv data) */ 198 /* v4l2_subdev and i2c reference (v4l2_subdev priv data) */
221 struct v4l2_subdev sd; 199 struct v4l2_subdev sd;
200 struct v4l2_ctrl_handler ctrl_handler;
222 /* private data structures */ 201 /* private data structures */
202 struct { /* si4713 control cluster */
203 /* This is one big cluster since the mute control
204 * powers off the device and after unmuting again all
205 * controls need to be set at once. The only way of doing
206 * that is by making it one big cluster. */
207 struct v4l2_ctrl *mute;
208 struct v4l2_ctrl *rds_ps_name;
209 struct v4l2_ctrl *rds_radio_text;
210 struct v4l2_ctrl *rds_pi;
211 struct v4l2_ctrl *rds_deviation;
212 struct v4l2_ctrl *rds_pty;
213 struct v4l2_ctrl *compression_enabled;
214 struct v4l2_ctrl *compression_threshold;
215 struct v4l2_ctrl *compression_gain;
216 struct v4l2_ctrl *compression_attack_time;
217 struct v4l2_ctrl *compression_release_time;
218 struct v4l2_ctrl *pilot_tone_enabled;
219 struct v4l2_ctrl *pilot_tone_freq;
220 struct v4l2_ctrl *pilot_tone_deviation;
221 struct v4l2_ctrl *limiter_enabled;
222 struct v4l2_ctrl *limiter_deviation;
223 struct v4l2_ctrl *limiter_release_time;
224 struct v4l2_ctrl *tune_preemphasis;
225 struct v4l2_ctrl *tune_pwr_level;
226 struct v4l2_ctrl *tune_ant_cap;
227 };
223 struct completion work; 228 struct completion work;
224 struct rds_info rds_info;
225 struct limiter_info limiter_info;
226 struct pilot_info pilot_info;
227 struct acomp_info acomp_info;
228 struct regulator_bulk_data supplies[SI4713_NUM_SUPPLIES]; 229 struct regulator_bulk_data supplies[SI4713_NUM_SUPPLIES];
229 int gpio_reset; 230 int gpio_reset;
231 u32 power_state;
232 u32 rds_enabled;
230 u32 frequency; 233 u32 frequency;
231 u32 preemphasis; 234 u32 preemphasis;
232 u32 mute;
233 u32 power_level;
234 u32 power_state;
235 u32 antenna_capacitor;
236 u32 stereo; 235 u32 stereo;
237 u32 tune_rnl; 236 u32 tune_rnl;
238}; 237};