aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2014-07-21 09:45:37 -0400
committerMauro Carvalho Chehab <m.chehab@samsung.com>2014-07-25 18:26:14 -0400
commit811c508104d092683ea5fe86cdcfd23dded22934 (patch)
tree0e14e357a96af19303a945e5ba0a29993a7ca986
parent1612f20ea025f55741b2d6e8b9c91047a7324a76 (diff)
[media] v4l2-ctrls: add new RDS TX controls
The si4713 supports several RDS features not yet implemented in the driver. This patch adds the missing RDS functionality to the list of RDS controls. The ALT_FREQS control is a compound control containing an array of up to 25 (the maximum according to the RDS standard) frequencies. To support that the V4L2_CTRL_TYPE_U32 was added. Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> Cc: Eduardo Valentin <edubezval@gmail.com> Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
-rw-r--r--drivers/media/v4l2-core/v4l2-ctrls.c35
-rw-r--r--include/media/v4l2-ctrls.h2
-rw-r--r--include/uapi/linux/v4l2-controls.h9
-rw-r--r--include/uapi/linux/videodev2.h2
4 files changed, 48 insertions, 0 deletions
diff --git a/drivers/media/v4l2-core/v4l2-ctrls.c b/drivers/media/v4l2-core/v4l2-ctrls.c
index 5db038525f99..4863cf05175d 100644
--- a/drivers/media/v4l2-core/v4l2-ctrls.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls.c
@@ -805,6 +805,15 @@ const char *v4l2_ctrl_get_name(u32 id)
805 case V4L2_CID_RDS_TX_PTY: return "RDS Program Type"; 805 case V4L2_CID_RDS_TX_PTY: return "RDS Program Type";
806 case V4L2_CID_RDS_TX_PS_NAME: return "RDS PS Name"; 806 case V4L2_CID_RDS_TX_PS_NAME: return "RDS PS Name";
807 case V4L2_CID_RDS_TX_RADIO_TEXT: return "RDS Radio Text"; 807 case V4L2_CID_RDS_TX_RADIO_TEXT: return "RDS Radio Text";
808 case V4L2_CID_RDS_TX_MONO_STEREO: return "RDS Stereo";
809 case V4L2_CID_RDS_TX_ARTIFICIAL_HEAD: return "RDS Artificial Head";
810 case V4L2_CID_RDS_TX_COMPRESSED: return "RDS Compressed";
811 case V4L2_CID_RDS_TX_DYNAMIC_PTY: return "RDS Dynamic PTY";
812 case V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT: return "RDS Traffic Announcement";
813 case V4L2_CID_RDS_TX_TRAFFIC_PROGRAM: return "RDS Traffic Program";
814 case V4L2_CID_RDS_TX_MUSIC_SPEECH: return "RDS Music";
815 case V4L2_CID_RDS_TX_ALT_FREQS_ENABLE: return "RDS Enable Alt Frequencies";
816 case V4L2_CID_RDS_TX_ALT_FREQS: return "RDS Alternate Frequencies";
808 case V4L2_CID_AUDIO_LIMITER_ENABLED: return "Audio Limiter Feature Enabled"; 817 case V4L2_CID_AUDIO_LIMITER_ENABLED: return "Audio Limiter Feature Enabled";
809 case V4L2_CID_AUDIO_LIMITER_RELEASE_TIME: return "Audio Limiter Release Time"; 818 case V4L2_CID_AUDIO_LIMITER_RELEASE_TIME: return "Audio Limiter Release Time";
810 case V4L2_CID_AUDIO_LIMITER_DEVIATION: return "Audio Limiter Deviation"; 819 case V4L2_CID_AUDIO_LIMITER_DEVIATION: return "Audio Limiter Deviation";
@@ -946,6 +955,14 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
946 case V4L2_CID_RF_TUNER_IF_GAIN_AUTO: 955 case V4L2_CID_RF_TUNER_IF_GAIN_AUTO:
947 case V4L2_CID_RF_TUNER_BANDWIDTH_AUTO: 956 case V4L2_CID_RF_TUNER_BANDWIDTH_AUTO:
948 case V4L2_CID_RF_TUNER_PLL_LOCK: 957 case V4L2_CID_RF_TUNER_PLL_LOCK:
958 case V4L2_CID_RDS_TX_MONO_STEREO:
959 case V4L2_CID_RDS_TX_ARTIFICIAL_HEAD:
960 case V4L2_CID_RDS_TX_COMPRESSED:
961 case V4L2_CID_RDS_TX_DYNAMIC_PTY:
962 case V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT:
963 case V4L2_CID_RDS_TX_TRAFFIC_PROGRAM:
964 case V4L2_CID_RDS_TX_MUSIC_SPEECH:
965 case V4L2_CID_RDS_TX_ALT_FREQS_ENABLE:
949 *type = V4L2_CTRL_TYPE_BOOLEAN; 966 *type = V4L2_CTRL_TYPE_BOOLEAN;
950 *min = 0; 967 *min = 0;
951 *max = *step = 1; 968 *max = *step = 1;
@@ -1089,6 +1106,9 @@ void v4l2_ctrl_fill(u32 id, const char **name, enum v4l2_ctrl_type *type,
1089 case V4L2_CID_DETECT_MD_THRESHOLD_GRID: 1106 case V4L2_CID_DETECT_MD_THRESHOLD_GRID:
1090 *type = V4L2_CTRL_TYPE_U16; 1107 *type = V4L2_CTRL_TYPE_U16;
1091 break; 1108 break;
1109 case V4L2_CID_RDS_TX_ALT_FREQS:
1110 *type = V4L2_CTRL_TYPE_U32;
1111 break;
1092 default: 1112 default:
1093 *type = V4L2_CTRL_TYPE_INTEGER; 1113 *type = V4L2_CTRL_TYPE_INTEGER;
1094 break; 1114 break;
@@ -1209,6 +1229,8 @@ static bool std_equal(const struct v4l2_ctrl *ctrl, u32 idx,
1209 return ptr1.p_u8[idx] == ptr2.p_u8[idx]; 1229 return ptr1.p_u8[idx] == ptr2.p_u8[idx];
1210 case V4L2_CTRL_TYPE_U16: 1230 case V4L2_CTRL_TYPE_U16:
1211 return ptr1.p_u16[idx] == ptr2.p_u16[idx]; 1231 return ptr1.p_u16[idx] == ptr2.p_u16[idx];
1232 case V4L2_CTRL_TYPE_U32:
1233 return ptr1.p_u32[idx] == ptr2.p_u32[idx];
1212 default: 1234 default:
1213 if (ctrl->is_int) 1235 if (ctrl->is_int)
1214 return ptr1.p_s32[idx] == ptr2.p_s32[idx]; 1236 return ptr1.p_s32[idx] == ptr2.p_s32[idx];
@@ -1242,6 +1264,9 @@ static void std_init(const struct v4l2_ctrl *ctrl, u32 idx,
1242 case V4L2_CTRL_TYPE_U16: 1264 case V4L2_CTRL_TYPE_U16:
1243 ptr.p_u16[idx] = ctrl->default_value; 1265 ptr.p_u16[idx] = ctrl->default_value;
1244 break; 1266 break;
1267 case V4L2_CTRL_TYPE_U32:
1268 ptr.p_u32[idx] = ctrl->default_value;
1269 break;
1245 default: 1270 default:
1246 idx *= ctrl->elem_size; 1271 idx *= ctrl->elem_size;
1247 memset(ptr.p + idx, 0, ctrl->elem_size); 1272 memset(ptr.p + idx, 0, ctrl->elem_size);
@@ -1289,6 +1314,9 @@ static void std_log(const struct v4l2_ctrl *ctrl)
1289 case V4L2_CTRL_TYPE_U16: 1314 case V4L2_CTRL_TYPE_U16:
1290 pr_cont("%u", (unsigned)*ptr.p_u16); 1315 pr_cont("%u", (unsigned)*ptr.p_u16);
1291 break; 1316 break;
1317 case V4L2_CTRL_TYPE_U32:
1318 pr_cont("%u", (unsigned)*ptr.p_u32);
1319 break;
1292 default: 1320 default:
1293 pr_cont("unknown type %d", ctrl->type); 1321 pr_cont("unknown type %d", ctrl->type);
1294 break; 1322 break;
@@ -1346,6 +1374,8 @@ static int std_validate(const struct v4l2_ctrl *ctrl, u32 idx,
1346 return ROUND_TO_RANGE(ptr.p_u8[idx], u8, ctrl); 1374 return ROUND_TO_RANGE(ptr.p_u8[idx], u8, ctrl);
1347 case V4L2_CTRL_TYPE_U16: 1375 case V4L2_CTRL_TYPE_U16:
1348 return ROUND_TO_RANGE(ptr.p_u16[idx], u16, ctrl); 1376 return ROUND_TO_RANGE(ptr.p_u16[idx], u16, ctrl);
1377 case V4L2_CTRL_TYPE_U32:
1378 return ROUND_TO_RANGE(ptr.p_u32[idx], u32, ctrl);
1349 1379
1350 case V4L2_CTRL_TYPE_BOOLEAN: 1380 case V4L2_CTRL_TYPE_BOOLEAN:
1351 ptr.p_s32[idx] = !!ptr.p_s32[idx]; 1381 ptr.p_s32[idx] = !!ptr.p_s32[idx];
@@ -1578,6 +1608,7 @@ static int check_range(enum v4l2_ctrl_type type,
1578 /* fall through */ 1608 /* fall through */
1579 case V4L2_CTRL_TYPE_U8: 1609 case V4L2_CTRL_TYPE_U8:
1580 case V4L2_CTRL_TYPE_U16: 1610 case V4L2_CTRL_TYPE_U16:
1611 case V4L2_CTRL_TYPE_U32:
1581 case V4L2_CTRL_TYPE_INTEGER: 1612 case V4L2_CTRL_TYPE_INTEGER:
1582 case V4L2_CTRL_TYPE_INTEGER64: 1613 case V4L2_CTRL_TYPE_INTEGER64:
1583 if (step == 0 || min > max || def < min || def > max) 1614 if (step == 0 || min > max || def < min || def > max)
@@ -1893,6 +1924,9 @@ static struct v4l2_ctrl *v4l2_ctrl_new(struct v4l2_ctrl_handler *hdl,
1893 case V4L2_CTRL_TYPE_U16: 1924 case V4L2_CTRL_TYPE_U16:
1894 elem_size = sizeof(u16); 1925 elem_size = sizeof(u16);
1895 break; 1926 break;
1927 case V4L2_CTRL_TYPE_U32:
1928 elem_size = sizeof(u32);
1929 break;
1896 default: 1930 default:
1897 if (type < V4L2_CTRL_COMPOUND_TYPES) 1931 if (type < V4L2_CTRL_COMPOUND_TYPES)
1898 elem_size = sizeof(s32); 1932 elem_size = sizeof(s32);
@@ -3248,6 +3282,7 @@ int __v4l2_ctrl_modify_range(struct v4l2_ctrl *ctrl,
3248 case V4L2_CTRL_TYPE_BITMASK: 3282 case V4L2_CTRL_TYPE_BITMASK:
3249 case V4L2_CTRL_TYPE_U8: 3283 case V4L2_CTRL_TYPE_U8:
3250 case V4L2_CTRL_TYPE_U16: 3284 case V4L2_CTRL_TYPE_U16:
3285 case V4L2_CTRL_TYPE_U32:
3251 if (ctrl->is_array) 3286 if (ctrl->is_array)
3252 return -EINVAL; 3287 return -EINVAL;
3253 ret = check_range(ctrl->type, min, max, step, def); 3288 ret = check_range(ctrl->type, min, max, step, def);
diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h
index d6540d201764..b7cd7a665e35 100644
--- a/include/media/v4l2-ctrls.h
+++ b/include/media/v4l2-ctrls.h
@@ -41,6 +41,7 @@ struct poll_table_struct;
41 * @p_s64: Pointer to a 64-bit signed value. 41 * @p_s64: Pointer to a 64-bit signed value.
42 * @p_u8: Pointer to a 8-bit unsigned value. 42 * @p_u8: Pointer to a 8-bit unsigned value.
43 * @p_u16: Pointer to a 16-bit unsigned value. 43 * @p_u16: Pointer to a 16-bit unsigned value.
44 * @p_u32: Pointer to a 32-bit unsigned value.
44 * @p_char: Pointer to a string. 45 * @p_char: Pointer to a string.
45 * @p: Pointer to a compound value. 46 * @p: Pointer to a compound value.
46 */ 47 */
@@ -49,6 +50,7 @@ union v4l2_ctrl_ptr {
49 s64 *p_s64; 50 s64 *p_s64;
50 u8 *p_u8; 51 u8 *p_u8;
51 u16 *p_u16; 52 u16 *p_u16;
53 u32 *p_u32;
52 char *p_char; 54 char *p_char;
53 void *p; 55 void *p;
54}; 56};
diff --git a/include/uapi/linux/v4l2-controls.h b/include/uapi/linux/v4l2-controls.h
index db526d1c8309..a13e6fef987e 100644
--- a/include/uapi/linux/v4l2-controls.h
+++ b/include/uapi/linux/v4l2-controls.h
@@ -757,6 +757,15 @@ enum v4l2_auto_focus_range {
757#define V4L2_CID_RDS_TX_PTY (V4L2_CID_FM_TX_CLASS_BASE + 3) 757#define V4L2_CID_RDS_TX_PTY (V4L2_CID_FM_TX_CLASS_BASE + 3)
758#define V4L2_CID_RDS_TX_PS_NAME (V4L2_CID_FM_TX_CLASS_BASE + 5) 758#define V4L2_CID_RDS_TX_PS_NAME (V4L2_CID_FM_TX_CLASS_BASE + 5)
759#define V4L2_CID_RDS_TX_RADIO_TEXT (V4L2_CID_FM_TX_CLASS_BASE + 6) 759#define V4L2_CID_RDS_TX_RADIO_TEXT (V4L2_CID_FM_TX_CLASS_BASE + 6)
760#define V4L2_CID_RDS_TX_MONO_STEREO (V4L2_CID_FM_TX_CLASS_BASE + 7)
761#define V4L2_CID_RDS_TX_ARTIFICIAL_HEAD (V4L2_CID_FM_TX_CLASS_BASE + 8)
762#define V4L2_CID_RDS_TX_COMPRESSED (V4L2_CID_FM_TX_CLASS_BASE + 9)
763#define V4L2_CID_RDS_TX_DYNAMIC_PTY (V4L2_CID_FM_TX_CLASS_BASE + 10)
764#define V4L2_CID_RDS_TX_TRAFFIC_ANNOUNCEMENT (V4L2_CID_FM_TX_CLASS_BASE + 11)
765#define V4L2_CID_RDS_TX_TRAFFIC_PROGRAM (V4L2_CID_FM_TX_CLASS_BASE + 12)
766#define V4L2_CID_RDS_TX_MUSIC_SPEECH (V4L2_CID_FM_TX_CLASS_BASE + 13)
767#define V4L2_CID_RDS_TX_ALT_FREQS_ENABLE (V4L2_CID_FM_TX_CLASS_BASE + 14)
768#define V4L2_CID_RDS_TX_ALT_FREQS (V4L2_CID_FM_TX_CLASS_BASE + 15)
760