Loading drivers/media/radio/radio-iris.c +122 −0 Original line number Diff line number Diff line Loading @@ -120,6 +120,7 @@ struct iris_device { struct hci_fm_data_rd_rsp default_data; struct hci_fm_spur_data spur_data; unsigned char is_station_valid; struct hci_fm_blend_table blend_tbl; }; static struct video_device *priv_videodev; Loading Loading @@ -1249,6 +1250,31 @@ static int hci_fm_get_ch_det_th(struct radio_hci_dev *hdev, return radio_hci_send_cmd(hdev, opcode, 0, NULL); } static int hci_fm_get_blend_tbl(struct radio_hci_dev *hdev, unsigned long param) { u16 opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ, HCI_OCF_FM_GET_BLND_TBL); return radio_hci_send_cmd(hdev, opcode, 0, NULL); } static int hci_fm_set_blend_tbl(struct radio_hci_dev *hdev, unsigned long param) { struct hci_fm_blend_table *blnd_tbl = (struct hci_fm_blend_table *) param; u16 opcode; if (blnd_tbl == NULL) { FMDERR("%s, blend tbl is null\n", __func__); return -EINVAL; } opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ, HCI_OCF_FM_SET_BLND_TBL); return radio_hci_send_cmd(hdev, opcode, sizeof(struct hci_fm_blend_table), blnd_tbl); } static int radio_hci_err(__u32 code) { switch (code) { Loading Loading @@ -1691,6 +1717,16 @@ static int hci_fm_get_spur_tbl_data(struct radio_hci_dev *hdev, return radio_hci_send_cmd(hdev, opcode, sizeof(int), &spur_freq); } static int hci_set_blend_tbl_req(struct hci_fm_blend_table *arg, struct radio_hci_dev *hdev) { int ret = 0; struct hci_fm_blend_table *blend_tbl = arg; ret = radio_hci_request(hdev, hci_fm_set_blend_tbl, (unsigned long)blend_tbl, RADIO_HCI_TIMEOUT); return ret; } static int hci_cmd(unsigned int cmd, struct radio_hci_dev *hdev) { int ret = 0; Loading Loading @@ -1783,6 +1819,10 @@ static int hci_cmd(unsigned int cmd, struct radio_hci_dev *hdev) ret = radio_hci_request(hdev, hci_fm_get_ch_det_th, arg, msecs_to_jiffies(RADIO_HCI_TIMEOUT)); break; case HCI_FM_GET_BLND_TBL_CMD: ret = radio_hci_request(hdev, hci_fm_get_blend_tbl, arg, msecs_to_jiffies(RADIO_HCI_TIMEOUT)); break; default: ret = -EINVAL; break; Loading Loading @@ -2274,6 +2314,28 @@ static void hci_cc_get_ch_det_threshold_rsp(struct radio_hci_dev *hdev, radio_hci_req_complete(hdev, status); } static void hci_cc_get_blend_tbl_rsp(struct radio_hci_dev *hdev, struct sk_buff *skb) { struct iris_device *radio = video_get_drvdata(video_get_dev()); u8 status; if (unlikely(radio == NULL)) { FMDERR(":radio is null"); return; } if (unlikely(skb == NULL)) { FMDERR("%s, socket buffer is null\n", __func__); return; } status = skb->data[0]; if (!status) memcpy(&radio->blend_tbl, &skb->data[1], sizeof(struct hci_fm_blend_table)); radio_hci_req_complete(hdev, status); } static inline void hci_cmd_complete_event(struct radio_hci_dev *hdev, struct sk_buff *skb) { Loading Loading @@ -2316,6 +2378,7 @@ static inline void hci_cmd_complete_event(struct radio_hci_dev *hdev, case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_EN_WAN_AVD_CTRL): case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_EN_NOTCH_CTRL): case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_SET_CH_DET_THRESHOLD): case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_SET_BLND_TBL): case hci_trans_ctrl_cmd_op_pack(HCI_OCF_FM_RDS_RT_REQ): case hci_trans_ctrl_cmd_op_pack(HCI_OCF_FM_RDS_PS_REQ): case hci_common_cmd_op_pack(HCI_OCF_FM_DEFAULT_DATA_WRITE): Loading Loading @@ -2388,6 +2451,9 @@ static inline void hci_cmd_complete_event(struct radio_hci_dev *hdev, case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_GET_CH_DET_THRESHOLD): hci_cc_get_ch_det_threshold_rsp(hdev, skb); break; case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_GET_BLND_TBL): hci_cc_get_blend_tbl_rsp(hdev, skb); break; default: FMDERR("%s opcode 0x%x", hdev->name, opcode); break; Loading Loading @@ -3507,6 +3573,22 @@ static int iris_vidioc_g_ctrl(struct file *file, void *priv, ctrl->value |= (cf0 << 24); } break; case V4L2_CID_PRIVATE_BLEND_SINRHI: retval = hci_cmd(HCI_FM_GET_BLND_TBL_CMD, radio->fm_hdev); if (retval < 0) { FMDERR("Failed to get blend table %d", retval); goto END; } ctrl->value = radio->blend_tbl.scBlendSinrHi; break; case V4L2_CID_PRIVATE_BLEND_RMSSIHI: retval = hci_cmd(HCI_FM_GET_BLND_TBL_CMD, radio->fm_hdev); if (retval < 0) { FMDERR("Failed to get blend table %d", retval); goto END; } ctrl->value = radio->blend_tbl.scBlendRmssiHi; break; default: retval = -EINVAL; break; Loading Loading @@ -4747,6 +4829,46 @@ static int iris_vidioc_s_ctrl(struct file *file, void *priv, if (retval < 0) FMDERR("get Spur data failed\n"); break; case V4L2_CID_PRIVATE_BLEND_SINRHI: if (!is_valid_blend_value(ctrl->value)) { FMDERR("%s: blend sinr count is not valid\n", __func__); retval = -EINVAL; goto END; } retval = hci_cmd(HCI_FM_GET_BLND_TBL_CMD, radio->fm_hdev); if (retval < 0) { FMDERR("Failed to get blend table %d", retval); goto END; } radio->blend_tbl.scBlendSinrHi = ctrl->value; retval = hci_set_blend_tbl_req(&radio->blend_tbl, radio->fm_hdev); if (retval < 0) { FMDERR("Failed to set blend tble %d ", retval); goto END; } break; case V4L2_CID_PRIVATE_BLEND_RMSSIHI: if (!is_valid_blend_value(ctrl->value)) { FMDERR("%s: blend rmssi count is not valid\n", __func__); retval = -EINVAL; goto END; } retval = hci_cmd(HCI_FM_GET_BLND_TBL_CMD, radio->fm_hdev); if (retval < 0) { FMDERR("Failed to get blend table %d", retval); goto END; } radio->blend_tbl.scBlendRmssiHi = ctrl->value; retval = hci_set_blend_tbl_req(&radio->blend_tbl, radio->fm_hdev); if (retval < 0) { FMDERR("Failed to set blend tble %d ", retval); goto END; } break; default: retval = -EINVAL; break; Loading include/uapi/media/radio-iris-commands.h +4 −0 Original line number Diff line number Diff line Loading @@ -72,6 +72,10 @@ enum v4l2_cid_private_iris_t { V4L2_CID_PRIVATE_SINRFIRSTSTAGE, V4L2_CID_PRIVATE_RMSSIFIRSTSTAGE, V4L2_CID_PRIVATE_RXREPEATCOUNT, V4L2_CID_PRIVATE_IRIS_RSSI_TH, V4L2_CID_PRIVATE_IRIS_AF_JUMP_RSSI_TH, V4L2_CID_PRIVATE_BLEND_SINRHI, V4L2_CID_PRIVATE_BLEND_RMSSIHI, /*using private CIDs under userclass*/ V4L2_CID_PRIVATE_IRIS_READ_DEFAULT = 0x00980928, Loading include/uapi/media/radio-iris.h +26 −0 Original line number Diff line number Diff line Loading @@ -77,6 +77,8 @@ const signed char MIN_SINR_TH = -128; const signed char MAX_SINR_TH = 127; const unsigned char MIN_SINR_SAMPLES = 0x01; const unsigned char MAX_SINR_SAMPLES = 0xFF; const signed char MIN_BLEND_HI = -128; const signed char MAX_BLEND_HI = 127; /* ---- HCI Packet structures ---- */ Loading Loading @@ -129,6 +131,7 @@ const unsigned char MAX_SINR_SAMPLES = 0xFF; #define FM_AF_LIST_MAX_SIZE 200 #define AF_LIST_MAX (FM_AF_LIST_MAX_SIZE / 4) /* Each AF frequency consist of sizeof(int) bytes */ #define MAX_BLEND_INDEX 49 /* HCI timeouts */ #define RADIO_HCI_TIMEOUT (10000) /* 10 seconds */ Loading Loading @@ -215,6 +218,8 @@ void radio_hci_event_packet(struct radio_hci_dev *hdev, struct sk_buff *skb); #define HCI_OCF_FM_SET_EVENT_MASK 0x0016 #define HCI_OCF_FM_SET_CH_DET_THRESHOLD 0x0017 #define HCI_OCF_FM_GET_CH_DET_THRESHOLD 0x0018 #define HCI_OCF_FM_SET_BLND_TBL 0x001B #define HCI_OCF_FM_GET_BLND_TBL 0x001C /* HCI trans control commans opcode*/ #define HCI_OCF_FM_ENABLE_TRANS_REQ 0x0001 #define HCI_OCF_FM_DISABLE_TRANS_REQ 0x0002 Loading Loading @@ -287,6 +292,7 @@ void radio_hci_event_packet(struct radio_hci_dev *hdev, struct sk_buff *skb); #define HCI_FM_DISABLE_TRANS_CMD 14 #define HCI_FM_GET_TX_CONFIG 15 #define HCI_FM_GET_DET_CH_TH_CMD 16 #define HCI_FM_GET_BLND_TBL_CMD 17 /* Defines for FM TX*/ #define TX_PS_DATA_LENGTH 108 Loading Loading @@ -415,6 +421,18 @@ struct hci_fm_ch_det_threshold { } __packed; struct hci_fm_blend_table { __u8 ucBlendType; __u8 ucBlendRampRateUp; __u8 ucBlendDebounceNumSampleUp; __u8 ucBlendDebounceIdxUp; __u8 ucBlendSinrIdxSkipStep; __u8 scBlendSinrHi; __u8 scBlendRmssiHi; __u8 ucBlendIndexHi; __u8 ucBlendIndex[MAX_BLEND_INDEX]; } __packed; /*HCI events*/ #define HCI_EV_TUNE_STATUS 0x01 #define HCI_EV_RDS_LOCK_STATUS 0x02 Loading Loading @@ -1092,4 +1110,12 @@ static inline int is_valid_fm_state(int state) return 0; } static inline int is_valid_blend_value(int val) { if ((val >= MIN_BLEND_HI) && (val <= MAX_BLEND_HI)) return 1; else return 0; } #endif /* __UAPI_RADIO_HCI_CORE_H */ Loading
drivers/media/radio/radio-iris.c +122 −0 Original line number Diff line number Diff line Loading @@ -120,6 +120,7 @@ struct iris_device { struct hci_fm_data_rd_rsp default_data; struct hci_fm_spur_data spur_data; unsigned char is_station_valid; struct hci_fm_blend_table blend_tbl; }; static struct video_device *priv_videodev; Loading Loading @@ -1249,6 +1250,31 @@ static int hci_fm_get_ch_det_th(struct radio_hci_dev *hdev, return radio_hci_send_cmd(hdev, opcode, 0, NULL); } static int hci_fm_get_blend_tbl(struct radio_hci_dev *hdev, unsigned long param) { u16 opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ, HCI_OCF_FM_GET_BLND_TBL); return radio_hci_send_cmd(hdev, opcode, 0, NULL); } static int hci_fm_set_blend_tbl(struct radio_hci_dev *hdev, unsigned long param) { struct hci_fm_blend_table *blnd_tbl = (struct hci_fm_blend_table *) param; u16 opcode; if (blnd_tbl == NULL) { FMDERR("%s, blend tbl is null\n", __func__); return -EINVAL; } opcode = hci_opcode_pack(HCI_OGF_FM_RECV_CTRL_CMD_REQ, HCI_OCF_FM_SET_BLND_TBL); return radio_hci_send_cmd(hdev, opcode, sizeof(struct hci_fm_blend_table), blnd_tbl); } static int radio_hci_err(__u32 code) { switch (code) { Loading Loading @@ -1691,6 +1717,16 @@ static int hci_fm_get_spur_tbl_data(struct radio_hci_dev *hdev, return radio_hci_send_cmd(hdev, opcode, sizeof(int), &spur_freq); } static int hci_set_blend_tbl_req(struct hci_fm_blend_table *arg, struct radio_hci_dev *hdev) { int ret = 0; struct hci_fm_blend_table *blend_tbl = arg; ret = radio_hci_request(hdev, hci_fm_set_blend_tbl, (unsigned long)blend_tbl, RADIO_HCI_TIMEOUT); return ret; } static int hci_cmd(unsigned int cmd, struct radio_hci_dev *hdev) { int ret = 0; Loading Loading @@ -1783,6 +1819,10 @@ static int hci_cmd(unsigned int cmd, struct radio_hci_dev *hdev) ret = radio_hci_request(hdev, hci_fm_get_ch_det_th, arg, msecs_to_jiffies(RADIO_HCI_TIMEOUT)); break; case HCI_FM_GET_BLND_TBL_CMD: ret = radio_hci_request(hdev, hci_fm_get_blend_tbl, arg, msecs_to_jiffies(RADIO_HCI_TIMEOUT)); break; default: ret = -EINVAL; break; Loading Loading @@ -2274,6 +2314,28 @@ static void hci_cc_get_ch_det_threshold_rsp(struct radio_hci_dev *hdev, radio_hci_req_complete(hdev, status); } static void hci_cc_get_blend_tbl_rsp(struct radio_hci_dev *hdev, struct sk_buff *skb) { struct iris_device *radio = video_get_drvdata(video_get_dev()); u8 status; if (unlikely(radio == NULL)) { FMDERR(":radio is null"); return; } if (unlikely(skb == NULL)) { FMDERR("%s, socket buffer is null\n", __func__); return; } status = skb->data[0]; if (!status) memcpy(&radio->blend_tbl, &skb->data[1], sizeof(struct hci_fm_blend_table)); radio_hci_req_complete(hdev, status); } static inline void hci_cmd_complete_event(struct radio_hci_dev *hdev, struct sk_buff *skb) { Loading Loading @@ -2316,6 +2378,7 @@ static inline void hci_cmd_complete_event(struct radio_hci_dev *hdev, case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_EN_WAN_AVD_CTRL): case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_EN_NOTCH_CTRL): case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_SET_CH_DET_THRESHOLD): case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_SET_BLND_TBL): case hci_trans_ctrl_cmd_op_pack(HCI_OCF_FM_RDS_RT_REQ): case hci_trans_ctrl_cmd_op_pack(HCI_OCF_FM_RDS_PS_REQ): case hci_common_cmd_op_pack(HCI_OCF_FM_DEFAULT_DATA_WRITE): Loading Loading @@ -2388,6 +2451,9 @@ static inline void hci_cmd_complete_event(struct radio_hci_dev *hdev, case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_GET_CH_DET_THRESHOLD): hci_cc_get_ch_det_threshold_rsp(hdev, skb); break; case hci_recv_ctrl_cmd_op_pack(HCI_OCF_FM_GET_BLND_TBL): hci_cc_get_blend_tbl_rsp(hdev, skb); break; default: FMDERR("%s opcode 0x%x", hdev->name, opcode); break; Loading Loading @@ -3507,6 +3573,22 @@ static int iris_vidioc_g_ctrl(struct file *file, void *priv, ctrl->value |= (cf0 << 24); } break; case V4L2_CID_PRIVATE_BLEND_SINRHI: retval = hci_cmd(HCI_FM_GET_BLND_TBL_CMD, radio->fm_hdev); if (retval < 0) { FMDERR("Failed to get blend table %d", retval); goto END; } ctrl->value = radio->blend_tbl.scBlendSinrHi; break; case V4L2_CID_PRIVATE_BLEND_RMSSIHI: retval = hci_cmd(HCI_FM_GET_BLND_TBL_CMD, radio->fm_hdev); if (retval < 0) { FMDERR("Failed to get blend table %d", retval); goto END; } ctrl->value = radio->blend_tbl.scBlendRmssiHi; break; default: retval = -EINVAL; break; Loading Loading @@ -4747,6 +4829,46 @@ static int iris_vidioc_s_ctrl(struct file *file, void *priv, if (retval < 0) FMDERR("get Spur data failed\n"); break; case V4L2_CID_PRIVATE_BLEND_SINRHI: if (!is_valid_blend_value(ctrl->value)) { FMDERR("%s: blend sinr count is not valid\n", __func__); retval = -EINVAL; goto END; } retval = hci_cmd(HCI_FM_GET_BLND_TBL_CMD, radio->fm_hdev); if (retval < 0) { FMDERR("Failed to get blend table %d", retval); goto END; } radio->blend_tbl.scBlendSinrHi = ctrl->value; retval = hci_set_blend_tbl_req(&radio->blend_tbl, radio->fm_hdev); if (retval < 0) { FMDERR("Failed to set blend tble %d ", retval); goto END; } break; case V4L2_CID_PRIVATE_BLEND_RMSSIHI: if (!is_valid_blend_value(ctrl->value)) { FMDERR("%s: blend rmssi count is not valid\n", __func__); retval = -EINVAL; goto END; } retval = hci_cmd(HCI_FM_GET_BLND_TBL_CMD, radio->fm_hdev); if (retval < 0) { FMDERR("Failed to get blend table %d", retval); goto END; } radio->blend_tbl.scBlendRmssiHi = ctrl->value; retval = hci_set_blend_tbl_req(&radio->blend_tbl, radio->fm_hdev); if (retval < 0) { FMDERR("Failed to set blend tble %d ", retval); goto END; } break; default: retval = -EINVAL; break; Loading
include/uapi/media/radio-iris-commands.h +4 −0 Original line number Diff line number Diff line Loading @@ -72,6 +72,10 @@ enum v4l2_cid_private_iris_t { V4L2_CID_PRIVATE_SINRFIRSTSTAGE, V4L2_CID_PRIVATE_RMSSIFIRSTSTAGE, V4L2_CID_PRIVATE_RXREPEATCOUNT, V4L2_CID_PRIVATE_IRIS_RSSI_TH, V4L2_CID_PRIVATE_IRIS_AF_JUMP_RSSI_TH, V4L2_CID_PRIVATE_BLEND_SINRHI, V4L2_CID_PRIVATE_BLEND_RMSSIHI, /*using private CIDs under userclass*/ V4L2_CID_PRIVATE_IRIS_READ_DEFAULT = 0x00980928, Loading
include/uapi/media/radio-iris.h +26 −0 Original line number Diff line number Diff line Loading @@ -77,6 +77,8 @@ const signed char MIN_SINR_TH = -128; const signed char MAX_SINR_TH = 127; const unsigned char MIN_SINR_SAMPLES = 0x01; const unsigned char MAX_SINR_SAMPLES = 0xFF; const signed char MIN_BLEND_HI = -128; const signed char MAX_BLEND_HI = 127; /* ---- HCI Packet structures ---- */ Loading Loading @@ -129,6 +131,7 @@ const unsigned char MAX_SINR_SAMPLES = 0xFF; #define FM_AF_LIST_MAX_SIZE 200 #define AF_LIST_MAX (FM_AF_LIST_MAX_SIZE / 4) /* Each AF frequency consist of sizeof(int) bytes */ #define MAX_BLEND_INDEX 49 /* HCI timeouts */ #define RADIO_HCI_TIMEOUT (10000) /* 10 seconds */ Loading Loading @@ -215,6 +218,8 @@ void radio_hci_event_packet(struct radio_hci_dev *hdev, struct sk_buff *skb); #define HCI_OCF_FM_SET_EVENT_MASK 0x0016 #define HCI_OCF_FM_SET_CH_DET_THRESHOLD 0x0017 #define HCI_OCF_FM_GET_CH_DET_THRESHOLD 0x0018 #define HCI_OCF_FM_SET_BLND_TBL 0x001B #define HCI_OCF_FM_GET_BLND_TBL 0x001C /* HCI trans control commans opcode*/ #define HCI_OCF_FM_ENABLE_TRANS_REQ 0x0001 #define HCI_OCF_FM_DISABLE_TRANS_REQ 0x0002 Loading Loading @@ -287,6 +292,7 @@ void radio_hci_event_packet(struct radio_hci_dev *hdev, struct sk_buff *skb); #define HCI_FM_DISABLE_TRANS_CMD 14 #define HCI_FM_GET_TX_CONFIG 15 #define HCI_FM_GET_DET_CH_TH_CMD 16 #define HCI_FM_GET_BLND_TBL_CMD 17 /* Defines for FM TX*/ #define TX_PS_DATA_LENGTH 108 Loading Loading @@ -415,6 +421,18 @@ struct hci_fm_ch_det_threshold { } __packed; struct hci_fm_blend_table { __u8 ucBlendType; __u8 ucBlendRampRateUp; __u8 ucBlendDebounceNumSampleUp; __u8 ucBlendDebounceIdxUp; __u8 ucBlendSinrIdxSkipStep; __u8 scBlendSinrHi; __u8 scBlendRmssiHi; __u8 ucBlendIndexHi; __u8 ucBlendIndex[MAX_BLEND_INDEX]; } __packed; /*HCI events*/ #define HCI_EV_TUNE_STATUS 0x01 #define HCI_EV_RDS_LOCK_STATUS 0x02 Loading Loading @@ -1092,4 +1110,12 @@ static inline int is_valid_fm_state(int state) return 0; } static inline int is_valid_blend_value(int val) { if ((val >= MIN_BLEND_HI) && (val <= MAX_BLEND_HI)) return 1; else return 0; } #endif /* __UAPI_RADIO_HCI_CORE_H */