* [RFC/PATCH 0/8] Add FM TX support for TI WL127x and TI WL128x.
@ 2010-09-02 15:57 raja_mani
2010-09-02 15:57 ` [RFC/PATCH 1/8] drivers:media:video: Adding new CIDs for FM RX ctls raja_mani
0 siblings, 1 reply; 12+ messages in thread
From: raja_mani @ 2010-09-02 15:57 UTC (permalink / raw)
To: hverkuil, linux-media, mchehab; +Cc: matti.j.aaltonen, Raja Mani
From: Raja Mani <raja_mani@ti.com>
This is second set patches for TI FM driver. This adds FM TX support
for TI WL128x and TI Wl127x chipsets. Also , extends V4L2 control IDs (CID)
to support few FM RX features.
First set of TI FM driver patches are submitted for review in linux-media
& LKML and available under this link:
http://www.spinics.net/lists/linux-media/msg22096.html
http://lkml.org/lkml/2010/8/13/122
TI FM driver makes use of TI Shared Transport (solution for BT/FM/GPS combo chip)
and Shared Transport driver is available in mainline kernel staging
directory (/drivers/staging/ti-st).
Raja Mani (8):
drivers:media:video: Adding new CIDs for FM RX ctls
include:linux:videodev2: Define new CIDs for FM RX ctls
drivers:staging:ti-st: Sources for FM TX
drivers:staging:ti-st: Move get region func to FM RX module.
drivers:staging:ti-st: Code cleanup in FM Common module
drivers:staging:ti-st: Extend FM TX global data structure.
drivers:staging:ti-st: Link FM TX module API with FM V4L2 module
drivers:staging:ti-st: Include FM TX module in Makefile
drivers/media/video/v4l2-common.c | 16 ++
drivers/staging/ti-st/Makefile | 2 +-
drivers/staging/ti-st/fmdrv.h | 4 +
drivers/staging/ti-st/fmdrv_common.c | 39 ++--
drivers/staging/ti-st/fmdrv_common.h | 23 ++-
drivers/staging/ti-st/fmdrv_rx.c | 7 +
drivers/staging/ti-st/fmdrv_rx.h | 1 +
drivers/staging/ti-st/fmdrv_tx.c | 391 ++++++++++++++++++++++++++++++++++
drivers/staging/ti-st/fmdrv_tx.h | 37 ++++
drivers/staging/ti-st/fmdrv_v4l2.c | 243 +++++++++++++++++++--
include/linux/videodev2.h | 18 ++
11 files changed, 733 insertions(+), 48 deletions(-)
create mode 100644 drivers/staging/ti-st/fmdrv_tx.c
create mode 100644 drivers/staging/ti-st/fmdrv_tx.h
^ permalink raw reply [flat|nested] 12+ messages in thread
* [RFC/PATCH 1/8] drivers:media:video: Adding new CIDs for FM RX ctls
2010-09-02 15:57 [RFC/PATCH 0/8] Add FM TX support for TI WL127x and TI WL128x raja_mani
@ 2010-09-02 15:57 ` raja_mani
2010-09-02 15:57 ` [RFC/PATCH 2/8] include:linux:videodev2: Define " raja_mani
2010-09-08 20:11 ` [RFC/PATCH 1/8] drivers:media:video: Adding " Mauro Carvalho Chehab
0 siblings, 2 replies; 12+ messages in thread
From: raja_mani @ 2010-09-02 15:57 UTC (permalink / raw)
To: hverkuil, linux-media, mchehab; +Cc: matti.j.aaltonen, Raja Mani, Pramodh AG
From: Raja Mani <raja_mani@ti.com>
Add support for the following new Control IDs (CID)
V4L2_CID_FM_RX_CLASS - FM RX Tuner controls
V4L2_CID_FM_BAND - FM band
V4L2_CID_RSSI_THRESHOLD - RSSI Threshold
V4L2_CID_TUNE_AF - Alternative Frequency
Signed-off-by: Raja Mani <raja_mani@ti.com>
Signed-off-by: Pramodh AG <pramodh_ag@ti.com>
---
drivers/media/video/v4l2-common.c | 16 ++++++++++++++++
1 files changed, 16 insertions(+), 0 deletions(-)
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index 4e53b0b..33c3037 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -354,6 +354,12 @@ const char **v4l2_ctrl_get_menu(u32 id)
"75 useconds",
NULL,
};
+ static const char *fm_band[] = {
+ "87.5 - 108. MHz",
+ "76. - 90. MHz, Japan",
+ "65. - 74. MHz, OIRT",
+ NULL,
+ };
switch (id) {
case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
@@ -394,6 +400,8 @@ const char **v4l2_ctrl_get_menu(u32 id)
return colorfx;
case V4L2_CID_TUNE_PREEMPHASIS:
return tune_preemphasis;
+ case V4L2_CID_FM_BAND:
+ return fm_band;
default:
return NULL;
}
@@ -520,6 +528,10 @@ const char *v4l2_ctrl_get_name(u32 id)
case V4L2_CID_TUNE_PREEMPHASIS: return "Pre-emphasis settings";
case V4L2_CID_TUNE_POWER_LEVEL: return "Tune Power Level";
case V4L2_CID_TUNE_ANTENNA_CAPACITOR: return "Tune Antenna Capacitor";
+ case V4L2_CID_FM_RX_CLASS: return "FM Radio Tuner Controls";
+ case V4L2_CID_FM_BAND: return "FM Band";
+ case V4L2_CID_RSSI_THRESHOLD: return "RSSI Threshold";
+ case V4L2_CID_TUNE_AF: return "Alternative Frequency";
default:
return NULL;
@@ -585,6 +597,9 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste
case V4L2_CID_EXPOSURE_AUTO:
case V4L2_CID_COLORFX:
case V4L2_CID_TUNE_PREEMPHASIS:
+ case V4L2_CID_FM_BAND:
+ case V4L2_CID_RSSI_THRESHOLD:
+ case V4L2_CID_TUNE_AF:
qctrl->type = V4L2_CTRL_TYPE_MENU;
step = 1;
break;
@@ -596,6 +611,7 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste
case V4L2_CID_CAMERA_CLASS:
case V4L2_CID_MPEG_CLASS:
case V4L2_CID_FM_TX_CLASS:
+ case V4L2_CID_FM_RX_CLASS:
qctrl->type = V4L2_CTRL_TYPE_CTRL_CLASS;
qctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
min = max = step = def = 0;
--
1.5.6.3
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [RFC/PATCH 2/8] include:linux:videodev2: Define new CIDs for FM RX ctls
2010-09-02 15:57 ` [RFC/PATCH 1/8] drivers:media:video: Adding new CIDs for FM RX ctls raja_mani
@ 2010-09-02 15:57 ` raja_mani
2010-09-02 15:57 ` [RFC/PATCH 3/8] drivers:staging:ti-st: Sources for FM TX raja_mani
2010-09-08 20:13 ` [RFC/PATCH 2/8] include:linux:videodev2: Define new CIDs for FM RX ctls Mauro Carvalho Chehab
2010-09-08 20:11 ` [RFC/PATCH 1/8] drivers:media:video: Adding " Mauro Carvalho Chehab
1 sibling, 2 replies; 12+ messages in thread
From: raja_mani @ 2010-09-02 15:57 UTC (permalink / raw)
To: hverkuil, linux-media, mchehab; +Cc: matti.j.aaltonen, Raja Mani, Pramodh AG
From: Raja Mani <raja_mani@ti.com>
Extend V4L2 CID list to support
1) FM RX Tuner controls
2) FM band
3) RSSI Threshold
4) Alternative Frequency
Signed-off-by: Raja Mani <raja_mani@ti.com>
Signed-off-by: Pramodh AG <pramodh_ag@ti.com>
---
include/linux/videodev2.h | 18 ++++++++++++++++++
1 files changed, 18 insertions(+), 0 deletions(-)
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 7c99acf..2798137 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -964,6 +964,7 @@ struct v4l2_writeback_ioctl_data {
#define V4L2_CTRL_CLASS_MPEG 0x00990000 /* MPEG-compression controls */
#define V4L2_CTRL_CLASS_CAMERA 0x009a0000 /* Camera class controls */
#define V4L2_CTRL_CLASS_FM_TX 0x009b0000 /* FM Modulator control class */
+#define V4L2_CTRL_CLASS_FM_RX 0x009c0000 /* FM Tuner control class */
#define V4L2_CTRL_ID_MASK (0x0fffffff)
#define V4L2_CTRL_ID2CLASS(id) ((id) & 0x0fff0000UL)
@@ -1362,6 +1363,23 @@ enum v4l2_preemphasis {
#define V4L2_CID_TUNE_POWER_LEVEL (V4L2_CID_FM_TX_CLASS_BASE + 113)
#define V4L2_CID_TUNE_ANTENNA_CAPACITOR (V4L2_CID_FM_TX_CLASS_BASE + 114)
+/* FM Tuner class control IDs */
+#define V4L2_CID_FM_RX_CLASS_BASE (V4L2_CTRL_CLASS_FM_RX | 0x900)
+#define V4L2_CID_FM_RX_CLASS (V4L2_CTRL_CLASS_FM_RX | 1)
+
+#define V4L2_CID_FM_BAND (V4L2_CID_FM_RX_CLASS_BASE + 1)
+enum v4l2_fm_band {
+ V4L2_FM_BAND_OTHER = 0,
+ V4L2_FM_BAND_JAPAN = 1,
+ V4L2_FM_BAND_OIRT = 2
+};
+#define V4L2_CID_RSSI_THRESHOLD (V4L2_CID_FM_RX_CLASS_BASE + 2)
+#define V4L2_CID_TUNE_AF (V4L2_CID_FM_RX_CLASS_BASE + 3)
+enum v4l2_tune_af {
+ V4L2_FM_AF_OFF = 0,
+ V4L2_FM_AF_ON = 1
+};
+
/*
* T U N I N G
*/
--
1.5.6.3
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [RFC/PATCH 3/8] drivers:staging:ti-st: Sources for FM TX
2010-09-02 15:57 ` [RFC/PATCH 2/8] include:linux:videodev2: Define " raja_mani
@ 2010-09-02 15:57 ` raja_mani
2010-09-02 15:57 ` [RFC/PATCH 4/8] drivers:staging:ti-st: Move get region func to FM RX module raja_mani
2010-09-08 20:19 ` [RFC/PATCH 3/8] drivers:staging:ti-st: Sources for FM TX Mauro Carvalho Chehab
2010-09-08 20:13 ` [RFC/PATCH 2/8] include:linux:videodev2: Define new CIDs for FM RX ctls Mauro Carvalho Chehab
1 sibling, 2 replies; 12+ messages in thread
From: raja_mani @ 2010-09-02 15:57 UTC (permalink / raw)
To: hverkuil, linux-media, mchehab; +Cc: matti.j.aaltonen, Raja Mani, Pramodh AG
From: Raja Mani <raja_mani@ti.com>
This has implementation of FM TX functionality (for Wl127x and WL128x
chip) which are listed below,
1) frequency set.
2) stereo/nono mode selection.
3) RDS config.
4) mute/unmute mode config.
5) power level config.
6) preemphasis filter config, etc.
This will work on top of TI Shared Transport driver. It communicates with
TI FM V4L2 module and TI FM Common module to perform the actual FM TX operation.
Signed-off-by: Raja Mani <raja_mani@ti.com>
Signed-off-by: Pramodh AG <pramodh_ag@ti.com>
---
drivers/staging/ti-st/fmdrv_tx.c | 391 ++++++++++++++++++++++++++++++++++++++
drivers/staging/ti-st/fmdrv_tx.h | 37 ++++
2 files changed, 428 insertions(+), 0 deletions(-)
create mode 100644 drivers/staging/ti-st/fmdrv_tx.c
create mode 100644 drivers/staging/ti-st/fmdrv_tx.h
diff --git a/drivers/staging/ti-st/fmdrv_tx.c b/drivers/staging/ti-st/fmdrv_tx.c
new file mode 100644
index 0000000..55bf89a
--- /dev/null
+++ b/drivers/staging/ti-st/fmdrv_tx.c
@@ -0,0 +1,391 @@
+/*
+ * FM Driver for Connectivity chip of Texas Instruments.
+ * This sub-module of FM driver implements FM TX functionality.
+ *
+ * Copyright (C) 2010 Texas Instruments
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/delay.h>
+#include "fmdrv.h"
+#include "fmdrv_common.h"
+#include "fmdrv_tx.h"
+
+int fm_tx_set_stereo_mono(struct fmdrv_ops *fmdev, unsigned short mode)
+{
+ unsigned short payload;
+ int ret = 0;
+
+ if (fmdev->curr_fmmode != FM_MODE_TX) {
+ ret = -EPERM;
+ goto exit;
+ }
+ if (fmdev->tx_data.aud_mode == mode)
+ goto exit;
+
+ pr_debug("stereo mode: %d", (int)mode);
+
+ /* Set Stereo/Mono mode */
+ FM_STORE_LE16_TO_BE16(payload, (1 - mode));
+ ret = fmc_send_cmd(fmdev, MONO_SET, &payload, sizeof(payload),
+ &fmdev->maintask_completion, NULL, NULL);
+ FM_CHECK_SEND_CMD_STATUS(ret);
+
+ fmdev->tx_data.aud_mode = mode;
+exit:
+ return ret;
+}
+
+static int __set_rds_text(struct fmdrv_ops *fmdev, unsigned char *rds_text)
+{
+ unsigned short payload;
+ int ret;
+
+ ret = fmc_send_cmd(fmdev, RDS_DATA_SET, rds_text, strlen(rds_text),
+ &fmdev->maintask_completion, NULL, NULL);
+ FM_CHECK_SEND_CMD_STATUS(ret);
+
+ /* Scroll mode */
+ FM_STORE_LE16_TO_BE16(payload, (unsigned short)0x1);
+ ret = fmc_send_cmd(fmdev, DISPLAY_MODE_SET, &payload, sizeof(payload),
+ &fmdev->maintask_completion, NULL, NULL);
+ FM_CHECK_SEND_CMD_STATUS(ret);
+
+ return 0;
+}
+
+static int __set_rds_data_mode(struct fmdrv_ops *fmdev, unsigned char mode)
+{
+ unsigned short payload;
+ int ret;
+
+ /* Setting unique PI TODO: how unique? */
+ FM_STORE_LE16_TO_BE16(payload, (unsigned short)0xcafe);
+ ret = fmc_send_cmd(fmdev, PI_SET, &payload, sizeof(payload),
+ &fmdev->maintask_completion, NULL, NULL);
+ FM_CHECK_SEND_CMD_STATUS(ret);
+
+ /* Set decoder id */
+ FM_STORE_LE16_TO_BE16(payload, (unsigned short)0xa);
+ ret = fmc_send_cmd(fmdev, DI_SET, &payload, sizeof(payload),
+ &fmdev->maintask_completion, NULL, NULL);
+ FM_CHECK_SEND_CMD_STATUS(ret);
+
+ /* TODO: RDS_MODE_GET? */
+ return 0;
+}
+
+static int __set_rds_len(struct fmdrv_ops *fmdev, unsigned char type,
+ unsigned short len)
+{
+ unsigned short payload;
+ int ret;
+
+ len |= type << 8;
+ FM_STORE_LE16_TO_BE16(payload, len);
+ ret = fmc_send_cmd(fmdev, LENGHT_SET, &payload, sizeof(payload),
+ &fmdev->maintask_completion, NULL, NULL);
+
+ FM_CHECK_SEND_CMD_STATUS(ret);
+
+ /* TODO: LENGHT_GET? */
+ return 0;
+}
+
+int fm_tx_set_rds_mode(struct fmdrv_ops *fmdev, unsigned char rds_en_dis)
+{
+ unsigned short payload;
+ int ret;
+ unsigned char rds_text[] = "Zoom2\n";
+
+ if (fmdev->curr_fmmode != FM_MODE_TX)
+ return -EPERM;
+
+ pr_debug("rds_en_dis:%d(E:%d, D:%d)", rds_en_dis,
+ FM_RDS_ENABLE, FM_RDS_DISABLE);
+
+ if (rds_en_dis == FM_RDS_ENABLE) {
+ /* Set RDS length */
+ __set_rds_len(fmdev, 0, strlen(rds_text));
+ /* Set RDS text */
+ __set_rds_text(fmdev, rds_text);
+ /* Set RDS mode */
+ __set_rds_data_mode(fmdev, 0x0);
+ }
+
+ /* Send command to enable RDS */
+ if (rds_en_dis == FM_RDS_ENABLE)
+ FM_STORE_LE16_TO_BE16(payload, 0x01);
+ else
+ FM_STORE_LE16_TO_BE16(payload, 0x00);
+
+ ret = fmc_send_cmd(fmdev, RDS_DATA_ENB, &payload, sizeof(payload),
+ &fmdev->maintask_completion, NULL, NULL);
+ FM_CHECK_SEND_CMD_STATUS(ret);
+
+ if (rds_en_dis == FM_RDS_ENABLE) {
+ /* Set RDS length */
+ __set_rds_len(fmdev, 0, strlen(rds_text));
+ /* Set RDS text */
+ __set_rds_text(fmdev, rds_text);
+ }
+ fmdev->tx_data.rds.flag = rds_en_dis;
+
+ return 0;
+}
+
+int fm_tx_set_radio_text(struct fmdrv_ops *fmdev,
+ unsigned char *rds_text,
+ unsigned char rds_type)
+{
+ unsigned short payload;
+ int ret;
+
+ if (fmdev->curr_fmmode != FM_MODE_TX)
+ return -EPERM;
+
+ fm_tx_set_rds_mode(fmdev, 0);
+ /* Set RDS length */
+ __set_rds_len(fmdev, rds_type, strlen(rds_text));
+ /* Set RDS text */
+ __set_rds_text(fmdev, rds_text);
+ /* Set RDS mode */
+ __set_rds_data_mode(fmdev, 0x0);
+
+ FM_STORE_LE16_TO_BE16(payload, 1);
+ ret = fmc_send_cmd(fmdev, RDS_DATA_ENB, &payload, sizeof(payload),
+ &fmdev->maintask_completion, NULL, NULL);
+ FM_CHECK_SEND_CMD_STATUS(ret);
+
+ return 0;
+}
+
+int fm_tx_set_af(struct fmdrv_ops *fmdev, unsigned int af)
+{
+ unsigned short payload;
+ int ret;
+
+ if (fmdev->curr_fmmode != FM_MODE_TX)
+ return -EPERM;
+ pr_debug("AF: %d", af);
+
+ af = (af - 87500) / 100;
+ FM_STORE_LE16_TO_BE16(payload, (unsigned short)af);
+ ret = fmc_send_cmd(fmdev, TA_SET, &payload, sizeof(payload),
+ &fmdev->maintask_completion, NULL, NULL);
+ FM_CHECK_SEND_CMD_STATUS(ret);
+ return 0;
+}
+
+int fm_tx_set_region(struct fmdrv_ops *fmdev,
+ unsigned char region_to_set)
+{
+ unsigned short payload;
+ int ret;
+
+ if (region_to_set != FM_BAND_EUROPE_US &&
+ region_to_set != FM_BAND_JAPAN) {
+ pr_err("Invalid band\n");
+ return -EINVAL;
+ }
+
+ /* Send command to set the band */
+ FM_STORE_LE16_TO_BE16(payload, (unsigned short)region_to_set);
+ ret = fmc_send_cmd(fmdev, TX_BAND_SET, &payload, sizeof(payload),
+ &fmdev->maintask_completion, NULL, NULL);
+ FM_CHECK_SEND_CMD_STATUS(ret);
+
+ return 0;
+}
+
+int fm_tx_set_mute_mode(struct fmdrv_ops *fmdev,
+ unsigned char mute_mode_toset)
+{
+ unsigned short payload;
+ int ret;
+
+ if (fmdev->curr_fmmode != FM_MODE_TX)
+ return -EPERM;
+ pr_debug("tx: mute mode %ld", (unsigned long)mute_mode_toset);
+
+ FM_STORE_LE16_TO_BE16(payload, mute_mode_toset);
+ ret = fmc_send_cmd(fmdev, MUTE, &payload, sizeof(payload),
+ &fmdev->maintask_completion, NULL, NULL);
+ FM_CHECK_SEND_CMD_STATUS(ret);
+
+ return 0;
+}
+
+/* Set TX Audio I/O */
+static int __set_audio_io(struct fmdrv_ops *fmdev)
+{
+ struct fmtx_data *tx = &fmdev->tx_data;
+ unsigned short payload;
+ int ret;
+
+ /* Set Audio I/O Enable */
+ FM_STORE_LE16_TO_BE16(payload, tx->audio_io);
+ ret = fmc_send_cmd(fmdev, AUDIO_IO_SET, &payload, sizeof(payload),
+ &fmdev->maintask_completion, NULL, NULL);
+ FM_CHECK_SEND_CMD_STATUS(ret);
+
+ /* TODO: is audio set? */
+ return 0;
+}
+
+/* Start TX Transmission */
+static int __enable_xmit(struct fmdrv_ops *fmdev, unsigned char new_xmit_state)
+{
+ struct fmtx_data *tx = &fmdev->tx_data;
+ unsigned short payload;
+ unsigned long timeleft;
+ int ret;
+
+ /* Enable POWER_ENB interrupts */
+ FM_STORE_LE16_TO_BE16(payload, FM_POW_ENB_EVENT);
+ ret = fmc_send_cmd(fmdev, INT_MASK_SET, &payload, sizeof(payload),
+ &fmdev->maintask_completion, NULL, NULL);
+
+ /* Set Power Enable */
+ FM_STORE_LE16_TO_BE16(payload, new_xmit_state);
+ ret = fmc_send_cmd(fmdev, POWER_ENB_SET, &payload, sizeof(payload),
+ &fmdev->maintask_completion, NULL, NULL);
+ FM_CHECK_SEND_CMD_STATUS(ret);
+
+ /* Wait for Power Enabled */
+ init_completion(&fmdev->maintask_completion);
+ timeleft = wait_for_completion_timeout(&fmdev->maintask_completion,
+ FM_DRV_TX_TIMEOUT);
+ if (!timeleft) {
+ pr_err("Timeout(%d sec),didn't get tune ended interrupt",
+ jiffies_to_msecs(FM_DRV_TX_TIMEOUT) / 1000);
+ return -ETIMEDOUT;
+ }
+
+ set_bit(FM_CORE_TX_XMITING, &fmdev->flag);
+ tx->xmit_state = new_xmit_state;
+
+ return 0;
+}
+
+/* Set TX power level */
+int fm_tx_set_pwr_lvl(struct fmdrv_ops *fmdev, unsigned char new_pwr_lvl)
+{
+ unsigned short payload;
+ struct fmtx_data *tx = &fmdev->tx_data;
+ int ret;
+
+ if (fmdev->curr_fmmode != FM_MODE_TX)
+ return -EPERM;
+ pr_debug("tx: pwr_level_to_set %ld ", (long int)new_pwr_lvl);
+
+ /* If the core isn't ready update global variable */
+ if (!test_bit(FM_CORE_READY, &fmdev->flag)) {
+ tx->pwr_lvl = new_pwr_lvl;
+ return 0;
+ }
+
+ /* Set power level */
+ FM_STORE_LE16_TO_BE16(payload, new_pwr_lvl);
+ ret = fmc_send_cmd(fmdev, POWER_LEL_SET, &payload, sizeof(payload),
+ &fmdev->maintask_completion, NULL, NULL);
+ FM_CHECK_SEND_CMD_STATUS(ret);
+
+ /* TODO: is the power level set? */
+ tx->pwr_lvl = new_pwr_lvl;
+
+ return 0;
+}
+
+/* Sets FM TX pre-emphasis filter value (OFF, 50us, or 75us)
+ * Convert V4L2 specified filter values to chip specific filter values.
+ */
+int fm_tx_set_preemph_filter(struct fmdrv_ops *fmdev, unsigned int filter)
+{
+ struct fmtx_data *tx = &fmdev->tx_data;
+ unsigned short payload;
+ int ret;
+
+ if (fmdev->curr_fmmode != FM_MODE_TX)
+ return -EPERM;
+
+ FM_STORE_LE16_TO_BE16(payload, filter);
+ ret = fmc_send_cmd(fmdev, PREMPH_SET, &payload, sizeof(payload),
+ &fmdev->maintask_completion, NULL, NULL);
+ FM_CHECK_SEND_CMD_STATUS(ret);
+
+ tx->preemph = filter;
+ return ret;
+}
+
+/* Sets FM TX antenna impedence value */
+int fm_tx_set_ant_imp(struct fmdrv_ops *fmdev, unsigned char imp)
+{
+ unsigned short payload;
+ int ret;
+
+ if (fmdev->curr_fmmode != FM_MODE_TX)
+ return -EPERM;
+
+ FM_STORE_LE16_TO_BE16(payload, imp);
+ ret = fmc_send_cmd(fmdev, IMP_SET, &payload, sizeof(payload),
+ &fmdev->maintask_completion, NULL, NULL);
+ FM_CHECK_SEND_CMD_STATUS(ret);
+
+ return ret;
+}
+
+/* Set TX Frequency */
+int fm_tx_set_frequency(struct fmdrv_ops *fmdev, unsigned int freq_to_set)
+{
+ struct fmtx_data *tx = &fmdev->tx_data;
+ unsigned short payload, chanl_index;
+ int ret;
+
+ if (test_bit(FM_CORE_TX_XMITING, &fmdev->flag)) {
+ __enable_xmit(fmdev, 0);
+ clear_bit(FM_CORE_TX_XMITING, &fmdev->flag);
+ }
+
+ /* Enable FR, BL interrupts */
+ FM_STORE_LE16_TO_BE16(payload, (FM_FR_EVENT | FM_BL_EVENT));
+ ret = fmc_send_cmd(fmdev, INT_MASK_SET, &payload, sizeof(payload),
+ &fmdev->maintask_completion, NULL, NULL);
+
+ tx->tx_frq = (unsigned long)freq_to_set;
+ pr_debug("tx: freq_to_set %ld ", (long int)tx->tx_frq);
+
+ chanl_index = freq_to_set / 10;
+ /* Set current tuner channel */
+ FM_STORE_LE16_TO_BE16(payload, chanl_index);
+ ret = fmc_send_cmd(fmdev, CHANL_SET, &payload, sizeof(payload),
+ &fmdev->maintask_completion, NULL, NULL);
+ FM_CHECK_SEND_CMD_STATUS(ret);
+
+ fm_tx_set_pwr_lvl(fmdev, tx->pwr_lvl);
+ fm_tx_set_preemph_filter(fmdev, tx->preemph);
+
+ tx->audio_io = 0x01; /* I2S */
+ __set_audio_io(fmdev);
+
+ __enable_xmit(fmdev, 0x01); /* Enable transmission */
+
+ tx->aud_mode = FM_STEREO_MODE;
+ tx->rds.flag = FM_RDS_DISABLE;
+
+ return 0;
+}
+
diff --git a/drivers/staging/ti-st/fmdrv_tx.h b/drivers/staging/ti-st/fmdrv_tx.h
new file mode 100644
index 0000000..f61dace
--- /dev/null
+++ b/drivers/staging/ti-st/fmdrv_tx.h
@@ -0,0 +1,37 @@
+/*
+ * FM Driver for Connectivity chip of Texas Instruments.
+ * FM TX module header.
+ *
+ * Copyright (C) 2010 Texas Instruments
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef _FMDRV_TX_H
+#define _FMDRV_TX_H
+
+int fm_tx_set_frequency(struct fmdrv_ops*, unsigned int);
+int fm_tx_set_pwr_lvl(struct fmdrv_ops*, unsigned char);
+int fm_tx_set_region(struct fmdrv_ops*, unsigned char);
+int fm_tx_set_mute_mode(struct fmdrv_ops*, unsigned char);
+int fm_tx_set_stereo_mono(struct fmdrv_ops*, unsigned short);
+int fm_tx_set_rds_mode(struct fmdrv_ops*, unsigned char);
+int fm_tx_set_radio_text(struct fmdrv_ops*, unsigned char*, unsigned char);
+int fm_tx_set_af(struct fmdrv_ops*, unsigned int);
+int fm_tx_set_preemph_filter(struct fmdrv_ops*, unsigned int);
+int fm_tx_set_ant_imp(struct fmdrv_ops*, unsigned char);
+
+#endif
+
--
1.5.6.3
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [RFC/PATCH 4/8] drivers:staging:ti-st: Move get region func to FM RX module.
2010-09-02 15:57 ` [RFC/PATCH 3/8] drivers:staging:ti-st: Sources for FM TX raja_mani
@ 2010-09-02 15:57 ` raja_mani
2010-09-02 15:57 ` [RFC/PATCH 5/8] drivers:staging:ti-st: Code cleanup in FM Common module raja_mani
2010-09-08 20:19 ` [RFC/PATCH 3/8] drivers:staging:ti-st: Sources for FM TX Mauro Carvalho Chehab
1 sibling, 1 reply; 12+ messages in thread
From: raja_mani @ 2010-09-02 15:57 UTC (permalink / raw)
To: hverkuil, linux-media, mchehab; +Cc: matti.j.aaltonen, Raja Mani, Pramodh AG
From: Raja Mani <raja_mani@ti.com>
fm_rx_get_region() API is specific to FM RX module, So
moving this from FM Common module to FM RX module.
Signed-off-by: Raja Mani <raja_mani@ti.com>
Signed-off-by: Pramodh AG <pramodh_ag@ti.com>
---
drivers/staging/ti-st/fmdrv_rx.c | 7 +++++++
drivers/staging/ti-st/fmdrv_rx.h | 1 +
2 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/drivers/staging/ti-st/fmdrv_rx.c b/drivers/staging/ti-st/fmdrv_rx.c
index a9df59f..1213927 100644
--- a/drivers/staging/ti-st/fmdrv_rx.c
+++ b/drivers/staging/ti-st/fmdrv_rx.c
@@ -319,6 +319,13 @@ int fm_rx_get_currband_lowhigh_freq(struct fmdrv_ops *fmdev,
return 0;
}
+/* Returns current band index (0-Europe/US; 1-Japan) */
+int fm_rx_get_region(struct fmdrv_ops *fmdev, unsigned char *region)
+{
+ *region = fmdev->rx.region.region_index;
+ return 0;
+}
+
/* Sets band (0-Europe/US; 1-Japan) */
int fm_rx_set_region(struct fmdrv_ops *fmdev,
unsigned char region_to_set)
diff --git a/drivers/staging/ti-st/fmdrv_rx.h b/drivers/staging/ti-st/fmdrv_rx.h
index 2ca3eda..e89a175 100644
--- a/drivers/staging/ti-st/fmdrv_rx.h
+++ b/drivers/staging/ti-st/fmdrv_rx.h
@@ -51,6 +51,7 @@ int fm_rx_get_rssi_threshold(struct fmdrv_ops *, short*);
int fm_rx_get_rfdepend_softmute(struct fmdrv_ops *, unsigned char*);
int fm_rx_get_deemphasis_mode(struct fmdrv_ops *, unsigned short*);
int fm_rx_get_af_switch(struct fmdrv_ops *, unsigned char *);
+int fm_rx_get_region(struct fmdrv_ops*, unsigned char*);
#endif
--
1.5.6.3
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [RFC/PATCH 5/8] drivers:staging:ti-st: Code cleanup in FM Common module
2010-09-02 15:57 ` [RFC/PATCH 4/8] drivers:staging:ti-st: Move get region func to FM RX module raja_mani
@ 2010-09-02 15:57 ` raja_mani
2010-09-02 15:57 ` [RFC/PATCH 6/8] drivers:staging:ti-st: Extend FM TX global data structure raja_mani
0 siblings, 1 reply; 12+ messages in thread
From: raja_mani @ 2010-09-02 15:57 UTC (permalink / raw)
To: hverkuil, linux-media, mchehab; +Cc: matti.j.aaltonen, Raja Mani, Pramodh AG
From: Raja Mani <raja_mani@ti.com>
Code cleanup and bug fixes in TI FM Common module.
1) Remove fmc_get_region() API (since it moved to FM RX module)
2) Mute/Umute fix ( As v4l2 spec, MUTE_ON should 1 and MUTE_OFF should be 0)
3) Support for FM TX Antenna Impedance configuration.
Signed-off-by: Raja Mani <raja_mani@ti.com>
Signed-off-by: Pramodh AG <pramodh_ag@ti.com>
---
drivers/staging/ti-st/fmdrv_common.c | 39 +++++++++++++--------------------
drivers/staging/ti-st/fmdrv_common.h | 23 ++++++++++++++++++-
2 files changed, 36 insertions(+), 26 deletions(-)
diff --git a/drivers/staging/ti-st/fmdrv_common.c b/drivers/staging/ti-st/fmdrv_common.c
index 8152031..ec502b0 100644
--- a/drivers/staging/ti-st/fmdrv_common.c
+++ b/drivers/staging/ti-st/fmdrv_common.c
@@ -38,8 +38,7 @@
#include "fmdrv_common.h"
#include "st.h"
#include "fmdrv_rx.h"
-/* TODO: Enable when FM TX is supported */
-/* #include "fmdrv_tx.h" */
+#include "fmdrv_tx.h"
#ifndef DEBUG
#ifdef pr_info
@@ -188,6 +187,8 @@ static struct fm_reg_table fm_reg_info[] = {
{0x51, REG_RD, "MS_GET"},
{0x52, REG_WR, "PS_SCROLL_SPEED_SET"},
{0x52, REG_RD, "PS_SCROLL_SPEED_GET"},
+ {0x57, REG_WR, "ANT_IMP_SET"},
+ {0x57, REG_RD, "ANT_IMP_GET"},
};
/* Region info */
@@ -1507,9 +1508,8 @@ int fmc_set_frequency(struct fmdrv_ops *fmdev, unsigned int freq_to_set)
break;
case FM_MODE_TX:
- /* TODO: Enable when FM TX is supported */
- /* ret = fm_tx_set_frequency(fmdev, freq_to_set); */
- /* break; */
+ ret = fm_tx_set_frequency(fmdev, freq_to_set);
+ break;
default:
ret = -EINVAL;
@@ -1548,13 +1548,6 @@ exit:
return ret;
}
-/* Returns current band index (0-Europe/US; 1-Japan) */
-int fmc_get_region(struct fmdrv_ops *fmdev, unsigned char *region)
-{
- *region = fmdev->rx.region.region_index;
- return 0;
-}
-
int fmc_set_region(struct fmdrv_ops *fmdev, unsigned char region_to_set)
{
int ret;
@@ -1565,9 +1558,8 @@ int fmc_set_region(struct fmdrv_ops *fmdev, unsigned char region_to_set)
break;
case FM_MODE_TX:
- /* TODO: Enable when FM TX is supported */
- /* ret = fm_tx_set_region(fmdev, region_to_set); */
- /* break; */
+ ret = fm_tx_set_region(fmdev, region_to_set);
+ break;
default:
ret = -EINVAL;
@@ -1585,9 +1577,8 @@ int fmc_set_mute_mode(struct fmdrv_ops *fmdev, unsigned char mute_mode_toset)
break;
case FM_MODE_TX:
- /* TODO: Enable when FM TX is supported */
- /* ret = fm_tx_set_mute_mode(fmdev, mute_mode_toset); */
- /* break; */
+ ret = fm_tx_set_mute_mode(fmdev, mute_mode_toset);
+ break;
default:
ret = -EINVAL;
@@ -1605,9 +1596,8 @@ int fmc_set_stereo_mono(struct fmdrv_ops *fmdev, unsigned short mode)
break;
case FM_MODE_TX:
- /* TODO: Enable when FM TX is supported */
- /* ret = fm_tx_set_stereo_mono(fmdev, mode); */
- /* break; */
+ ret = fm_tx_set_stereo_mono(fmdev, mode);
+ break;
default:
ret = -EINVAL;
@@ -1625,9 +1615,8 @@ int fmc_set_rds_mode(struct fmdrv_ops *fmdev, unsigned char rds_en_dis)
break;
case FM_MODE_TX:
- /* TODO: Enable when FM TX is supported */
- /* ret = fm_tx_set_rds_mode(fmdev, rds_en_dis); */
- /* break; */
+ ret = fm_tx_set_rds_mode(fmdev, rds_en_dis);
+ break;
default:
ret = -EINVAL;
@@ -2101,6 +2090,8 @@ static int __init fm_drv_init(void)
fmdev->irq_info.fm_int_handlers = g_IntHandlerTable;
fmdev->curr_fmmode = FM_MODE_OFF;
+ fmdev->tx_data.pwr_lvl = FM_PWR_LVL_DEF;
+ fmdev->tx_data.preemph = FM_TX_PREEMPH_50US;
goto exit;
rel_rdsbuf:
diff --git a/drivers/staging/ti-st/fmdrv_common.h b/drivers/staging/ti-st/fmdrv_common.h
index 7fb55f3..9f60c2c 100644
--- a/drivers/staging/ti-st/fmdrv_common.h
+++ b/drivers/staging/ti-st/fmdrv_common.h
@@ -173,6 +173,8 @@ enum fm_reg_index {
MS_GET,
PS_SCROLL_SPEED_SET,
PS_SCROLL_SPEED_GET,
+ IMP_SET,
+ IMP_GET,
FM_REG_MAX_ENTRIES
};
@@ -300,8 +302,8 @@ struct bts_action_delay {
#define FM_RX_VOLUME_GAIN_STEP 0x370
/* Mute modes */
-#define FM_MUTE_ON 0
-#define FM_MUTE_OFF 1
+#define FM_MUTE_OFF 0
+#define FM_MUTE_ON 1
#define FM_MUTE_ATTENUATE 2
#define FM_RX_MUTE_UNMUTE_MODE 0x00
@@ -432,6 +434,23 @@ struct bts_action_delay {
#define FM_DEFAULT_RX_VOLUME 10
#define FM_DEFAULT_RSSI_THRESHOLD 3
+/* Range for TX power level in units for dB/uV */
+#define FM_PWR_LVL_LOW 91
+#define FM_PWR_LVL_HIGH 122
+
+/* Chip specific default TX power level value */
+#define FM_PWR_LVL_DEF 4
+
+/* FM TX Pre-emphasis filter values */
+#define FM_TX_PREEMPH_OFF 1
+#define FM_TX_PREEMPH_50US 0
+#define FM_TX_PREEMPH_75US 2
+
+/* FM TX antenna impedence values */
+#define FM_TX_ANT_IMP_50 0
+#define FM_TX_ANT_IMP_200 1
+#define FM_TX_ANT_IMP_500 2
+
/* Functions exported by FM common sub-module */
int fmc_prepare(struct fmdrv_ops *);
int fmc_release(struct fmdrv_ops *);
--
1.5.6.3
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [RFC/PATCH 6/8] drivers:staging:ti-st: Extend FM TX global data structure.
2010-09-02 15:57 ` [RFC/PATCH 5/8] drivers:staging:ti-st: Code cleanup in FM Common module raja_mani
@ 2010-09-02 15:57 ` raja_mani
2010-09-02 15:57 ` [RFC/PATCH 7/8] drivers:staging:ti-st: Link FM TX module API with FM V4L2 module raja_mani
0 siblings, 1 reply; 12+ messages in thread
From: raja_mani @ 2010-09-02 15:57 UTC (permalink / raw)
To: hverkuil, linux-media, mchehab; +Cc: matti.j.aaltonen, Raja Mani, Pramodh AG
From: Raja Mani <raja_mani@ti.com>
Add new members in FM TX global data structure (struct fmtx_data)
to track current Audio mode, Reemphasis and Region setting in TX mode.
Signed-off-by: Raja Mani <raja_mani@ti.com>
Signed-off-by: Pramodh AG <pramodh_ag@ti.com>
---
drivers/staging/ti-st/fmdrv.h | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/drivers/staging/ti-st/fmdrv.h b/drivers/staging/ti-st/fmdrv.h
index d560570..f8a4ce3 100644
--- a/drivers/staging/ti-st/fmdrv.h
+++ b/drivers/staging/ti-st/fmdrv.h
@@ -173,6 +173,7 @@ struct fm_rx {
struct tx_rds {
unsigned char text_type;
unsigned char text[25];
+ unsigned char flag;
unsigned int af_freq;
};
/*
@@ -187,6 +188,9 @@ struct fmtx_data {
unsigned char pwr_lvl;
unsigned char xmit_state;
unsigned char audio_io;
+ unsigned char region;
+ unsigned short aud_mode;
+ unsigned int preemph;
unsigned long tx_frq;
struct tx_rds rds;
};
--
1.5.6.3
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [RFC/PATCH 7/8] drivers:staging:ti-st: Link FM TX module API with FM V4L2 module
2010-09-02 15:57 ` [RFC/PATCH 6/8] drivers:staging:ti-st: Extend FM TX global data structure raja_mani
@ 2010-09-02 15:57 ` raja_mani
2010-09-02 15:58 ` [RFC/PATCH 8/8] drivers:staging:ti-st: Include FM TX module in Makefile raja_mani
0 siblings, 1 reply; 12+ messages in thread
From: raja_mani @ 2010-09-02 15:57 UTC (permalink / raw)
To: hverkuil, linux-media, mchehab; +Cc: matti.j.aaltonen, Raja Mani, Pramodh AG
From: Raja Mani <raja_mani@ti.com>
Add FM TX API calls in FM V4L2 module which will internally link to V4L2
subsystem. It includes ,
1) Support for set/get modulator attributes and extended control.
2) fm_v4l2_vidioc_s_ctrl ()
+ added support for V4L2_CID_TUNE_POWER_LEVEL,
V4L2_CID_TUNE_PREEMPHASIS, V4L2_CID_FM_BAND,
V4L2_CID_TUNE_ANTENNA_CAPACITOR
3) fm_v4l2_vidioc_g_ctrl ()
+ added support for V4L2_CID_TUNE_PREEMPHASIS, V4L2_CID_FM_BAND
Signed-off-by: Raja Mani <raja_mani@ti.com>
Signed-off-by: Pramodh AG <pramodh_ag@ti.com>
---
drivers/staging/ti-st/fmdrv_v4l2.c | 243 ++++++++++++++++++++++++++++++++---
1 files changed, 222 insertions(+), 21 deletions(-)
diff --git a/drivers/staging/ti-st/fmdrv_v4l2.c b/drivers/staging/ti-st/fmdrv_v4l2.c
index c546a0f..d76344e 100644
--- a/drivers/staging/ti-st/fmdrv_v4l2.c
+++ b/drivers/staging/ti-st/fmdrv_v4l2.c
@@ -30,8 +30,7 @@
#include "fmdrv_v4l2.h"
#include "fmdrv_common.h"
#include "fmdrv_rx.h"
-/* TODO: Enable when FM TX is supported */
-/* #include "fmdrv_tx.h" */
+#include "fmdrv_tx.h"
#ifndef DEBUG
#ifdef pr_info
@@ -134,9 +133,8 @@ static ssize_t fm_v4l2_fops_write(struct file *file, const char __user * buf,
ret, rds.text_type, rds.text, rds.af_freq);
fmdev = video_drvdata(file);
- /* TODO: Enable when FM TX is supported */
- /* fm_tx_set_radio_text(fmdev, rds.text, rds.text_type); */
- /* fm_tx_set_af(fmdev, rds.af_freq); */
+ fm_tx_set_radio_text(fmdev, rds.text, rds.text_type);
+ fm_tx_set_af(fmdev, rds.af_freq);
return 0;
}
@@ -257,6 +255,9 @@ static int fm_v4l2_vidioc_g_ctrl(struct file *file, void *priv,
int ret = -EINVAL;
unsigned short curr_vol;
unsigned char curr_mute_mode;
+ unsigned char region;
+ unsigned char afreq;
+ short threshold;
struct fmdrv_ops *fmdev;
fmdev = video_drvdata(file);
@@ -274,16 +275,48 @@ static int fm_v4l2_vidioc_g_ctrl(struct file *file, void *priv,
goto exit;
ctrl->value = curr_vol;
break;
+ case V4L2_CID_FM_BAND:
+ if (fmdev->curr_fmmode != FM_MODE_RX)
+ break;
+ ret = fm_rx_get_region(fmdev, ®ion);
+ if (ret < 0)
+ break;
+ if (region == FM_BAND_EUROPE_US)
+ ctrl->value = V4L2_FM_BAND_OTHER;
+ else
+ ctrl->value = V4L2_FM_BAND_JAPAN;
+ break;
+ case V4L2_CID_RSSI_THRESHOLD:
+ ret = fm_rx_get_rssi_threshold(fmdev, &threshold);
+ if (ret == 0)
+ ctrl->value = threshold;
+ break;
+ case V4L2_CID_TUNE_AF:
+ ret = fm_rx_get_af_switch(fmdev, &afreq);
+ if (ret == 0)
+ ctrl->value = afreq;
+ break;
+ case V4L2_CID_TUNE_PREEMPHASIS:
+ ctrl->value = fmdev->tx_data.preemph;
+ break;
}
exit:
return ret;
}
+/* Change the value of specified control.
+ * V4L2_CID_TUNE_POWER_LEVEL: Application will specify power level value in
+ * units of dB/uV, whereas range and step are specific to FM chip. For TI's WL
+ * chips, convert application specified power level value to chip specific
+ * value by substracting it with 122. Refer to TI FM data sheet for details.
+ */
static int fm_v4l2_vidioc_s_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
int ret = -EINVAL;
+ unsigned int emph_filter;
+ unsigned char region;
struct fmdrv_ops *fmdev;
fmdev = video_drvdata(file);
@@ -291,17 +324,61 @@ static int fm_v4l2_vidioc_s_ctrl(struct file *file, void *priv,
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE: /* set mute */
ret = fmc_set_mute_mode(fmdev, (unsigned char)ctrl->value);
- if (ret < 0)
- goto exit;
break;
case V4L2_CID_AUDIO_VOLUME: /* set volume */
ret = fm_rx_set_volume(fmdev, (unsigned short)ctrl->value);
- if (ret < 0)
- goto exit;
+ break;
+ case V4L2_CID_TUNE_POWER_LEVEL: /* set TX power level - ext control */
+ if (ctrl->value >= FM_PWR_LVL_LOW &&
+ ctrl->value <= FM_PWR_LVL_HIGH) {
+ ctrl->value = FM_PWR_LVL_HIGH - ctrl->value;
+ ret = fm_tx_set_pwr_lvl(fmdev,
+ (unsigned char)ctrl->value);
+ } else
+ ret = -ERANGE;
+ break;
+ case V4L2_CID_FM_BAND:
+ if (ctrl->value < V4L2_FM_BAND_OTHER ||
+ ctrl->value > V4L2_FM_BAND_JAPAN) {
+ ret = -ERANGE;
+ break;
+ }
+ if (ctrl->value == V4L2_FM_BAND_OTHER)
+ region = FM_BAND_EUROPE_US;
+ else
+ region = FM_BAND_JAPAN;
+ ret = fmc_set_region(fmdev, region);
+ break;
+ case V4L2_CID_RSSI_THRESHOLD:
+ ret = fm_rx_set_rssi_threshold(fmdev, (short)ctrl->value);
+ break;
+ case V4L2_CID_TUNE_AF:
+ ret = fm_rx_set_af_switch(fmdev, (unsigned char)ctrl->value);
+ break;
+ case V4L2_CID_TUNE_PREEMPHASIS:
+ if (ctrl->value < V4L2_PREEMPHASIS_DISABLED ||
+ ctrl->value > V4L2_PREEMPHASIS_75_uS) {
+ ret = -EINVAL;
+ break;
+ }
+ if (ctrl->value == V4L2_PREEMPHASIS_DISABLED)
+ emph_filter = FM_TX_PREEMPH_OFF;
+ else if (ctrl->value == V4L2_PREEMPHASIS_50_uS)
+ emph_filter = FM_TX_PREEMPH_50US;
+ else
+ emph_filter = FM_TX_PREEMPH_75US;
+ ret = fm_tx_set_preemph_filter(fmdev, emph_filter);
+ break;
+ case V4L2_CID_TUNE_ANTENNA_CAPACITOR:
+ if (ctrl->value == FM_TX_ANT_IMP_50 ||
+ ctrl->value == FM_TX_ANT_IMP_200 ||
+ ctrl->value == FM_TX_ANT_IMP_500)
+ ret = fm_tx_set_ant_imp(fmdev, ctrl->value);
+ else
+ ret = -EINVAL;
break;
}
-exit:
return ret;
}
@@ -324,7 +401,7 @@ static int fm_v4l2_vidioc_s_audio(struct file *file, void *priv,
return 0;
}
-/* Get tuner attributes. If current mode is NOT RX, set to RX */
+/* Get tuner attributes. If current mode is NOT RX, return error */
static int fm_v4l2_vidioc_g_tuner(struct file *file, void *priv,
struct v4l2_tuner *tuner)
{
@@ -340,12 +417,8 @@ static int fm_v4l2_vidioc_g_tuner(struct file *file, void *priv,
fmdev = video_drvdata(file);
if (fmdev->curr_fmmode != FM_MODE_RX) {
- ret = fmc_set_mode(fmdev, FM_MODE_RX);
- if (ret < 0) {
- pr_err("(fmdrv): Failed to set RX mode; unable to " \
- "read tuner attributes\n");
- goto exit;
- }
+ ret = -EPERM;
+ goto exit;
}
ret = fm_rx_get_currband_lowhigh_freq(fmdev, &bottom_frequency,
@@ -364,11 +437,12 @@ static int fm_v4l2_vidioc_g_tuner(struct file *file, void *priv,
strcpy(tuner->name, "FM");
tuner->type = V4L2_TUNER_RADIO;
/* Store rangelow and rangehigh freq in unit of 62.5 KHz */
- tuner->rangelow = (bottom_frequency * 10000) / 625;
- tuner->rangehigh = (top_frequency * 10000) / 625;
+ tuner->rangelow = bottom_frequency * 16;
+ tuner->rangehigh = top_frequency * 16;
tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO |
((fmdev->rx.rds.flag == FM_RDS_ENABLE) ? V4L2_TUNER_SUB_RDS : 0);
- tuner->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_RDS;
+ tuner->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_RDS |
+ V4L2_TUNER_CAP_LOW;
tuner->audmode = (stereo_mono_mode ?
V4L2_TUNER_MODE_MONO : V4L2_TUNER_MODE_STEREO);
@@ -440,6 +514,8 @@ static int fm_v4l2_vidioc_g_frequency(struct file *file, void *priv,
ret = fmc_get_frequency(fmdev, &freq->frequency);
if (ret < 0)
return ret;
+
+ freq->frequency *= 16; /* unit of 62.5 */
return 0;
}
@@ -451,6 +527,13 @@ static int fm_v4l2_vidioc_s_frequency(struct file *file, void *priv,
struct fmdrv_ops *fmdev;
fmdev = video_drvdata(file);
+
+ /*
+ * As per V4L2 specifications user sends the frequency
+ * in units of 62.5.
+ */
+ freq->frequency = (unsigned int)(freq->frequency / 16);
+
ret = fmc_set_frequency(fmdev, freq->frequency);
if (ret < 0)
return ret;
@@ -482,6 +565,120 @@ exit:
return ret;
}
+static int fm_v4l2_vidioc_g_ext_ctrls(struct file *file, void *priv,
+ struct v4l2_ext_controls *ext_ctrls)
+{
+ int index;
+ int ret = -EINVAL;
+ struct v4l2_control ctrl;
+
+ if (V4L2_CTRL_CLASS_FM_TX == ext_ctrls->ctrl_class) {
+ for (index = 0; index < ext_ctrls->count; index++) {
+ ctrl.id = ext_ctrls->controls[index].id;
+ ctrl.value = ext_ctrls->controls[index].value;
+ ret = fm_v4l2_vidioc_g_ctrl(file, priv, &ctrl);
+ if (ret < 0) {
+ ext_ctrls->error_idx = index;
+ break;
+ }
+ ext_ctrls->controls[index].value = ctrl.value;
+ }
+ }
+ return ret;
+}
+
+static int fm_v4l2_vidioc_s_ext_ctrls(struct file *file, void *priv,
+ struct v4l2_ext_controls *ext_ctrls)
+{
+ int index;
+ int ret = -EINVAL;
+ struct v4l2_control ctrl;
+
+ if (V4L2_CTRL_CLASS_FM_TX == ext_ctrls->ctrl_class) {
+ for (index = 0; index < ext_ctrls->count; index++) {
+ ctrl.id = ext_ctrls->controls[index].id;
+ ctrl.value = ext_ctrls->controls[index].value;
+ ret = fm_v4l2_vidioc_s_ctrl(file, priv, &ctrl);
+ if (ret < 0) {
+ ext_ctrls->error_idx = index;
+ break;
+ }
+ ext_ctrls->controls[index].value = ctrl.value;
+ }
+ }
+ return ret;
+}
+
+/* Get modulator attributes. If mode is not TX, return no attributes. */
+static int fm_v4l2_vidioc_g_modulator(struct file *file, void *priv,
+ struct v4l2_modulator *mod)
+{
+ int ret = -EPERM;
+ struct fmdrv_ops *fmdev;
+
+ if (mod->index != 0) {
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ fmdev = video_drvdata(file);
+ if (fmdev->curr_fmmode != FM_MODE_TX)
+ goto exit;
+
+ mod->txsubchans = ((fmdev->tx_data.aud_mode == FM_STEREO_MODE) ?
+ V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO) |
+ ((fmdev->tx_data.rds.flag == FM_RDS_ENABLE) ? V4L2_TUNER_SUB_RDS : 0);
+
+ mod->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_RDS;
+ ret = 0;
+exit:
+ return ret;
+}
+
+/* Set modulator attributes. If mode is not TX, set to TX. */
+static int fm_v4l2_vidioc_s_modulator(struct file *file, void *priv,
+ struct v4l2_modulator *mod)
+{
+ unsigned char rds_mode;
+ unsigned short aud_mode;
+ int ret;
+ struct fmdrv_ops *fmdev;
+
+ if (mod->index != 0) {
+ ret = -EINVAL;
+ goto exit;
+ }
+
+ fmdev = video_drvdata(file);
+ if (fmdev->curr_fmmode != FM_MODE_TX) {
+ ret = fmc_set_mode(fmdev, FM_MODE_TX);
+ if (ret != 0) {
+ pr_err("(fmdrv): Failed to set TX mode; unable to " \
+ "set modulator attributes\n");
+ goto exit;
+ }
+ }
+
+ aud_mode = (mod->txsubchans & V4L2_TUNER_SUB_STEREO) ?
+ FM_STEREO_MODE : FM_MONO_MODE;
+ rds_mode = (mod->txsubchans & V4L2_TUNER_SUB_RDS) ?
+ FM_RDS_ENABLE : FM_RDS_DISABLE;
+
+ ret = fm_tx_set_stereo_mono(fmdev, aud_mode);
+ if (ret < 0) {
+ pr_err("(fmdrv): Failed to set mono/stereo mode for TX\n");
+ goto exit;
+ }
+
+ ret = fm_tx_set_rds_mode(fmdev, rds_mode);
+ if (ret < 0) {
+ pr_err("(fmdrv): Failed to set rds mode for TX\n");
+ goto exit;
+ }
+exit:
+ return ret;
+}
+
static const struct v4l2_file_operations fm_drv_fops = {
.owner = THIS_MODULE,
.read = fm_v4l2_fops_read,
@@ -497,13 +694,17 @@ static const struct v4l2_ioctl_ops fm_drv_ioctl_ops = {
.vidioc_queryctrl = fm_v4l2_vidioc_queryctrl,
.vidioc_g_ctrl = fm_v4l2_vidioc_g_ctrl,
.vidioc_s_ctrl = fm_v4l2_vidioc_s_ctrl,
+ .vidioc_g_ext_ctrls = fm_v4l2_vidioc_g_ext_ctrls,
+ .vidioc_s_ext_ctrls = fm_v4l2_vidioc_s_ext_ctrls,
.vidioc_g_audio = fm_v4l2_vidioc_g_audio,
.vidioc_s_audio = fm_v4l2_vidioc_s_audio,
.vidioc_g_tuner = fm_v4l2_vidioc_g_tuner,
.vidioc_s_tuner = fm_v4l2_vidioc_s_tuner,
.vidioc_g_frequency = fm_v4l2_vidioc_g_frequency,
.vidioc_s_frequency = fm_v4l2_vidioc_s_frequency,
- .vidioc_s_hw_freq_seek = fm_v4l2_vidioc_s_hw_freq_seek
+ .vidioc_s_hw_freq_seek = fm_v4l2_vidioc_s_hw_freq_seek,
+ .vidioc_g_modulator = fm_v4l2_vidioc_g_modulator,
+ .vidioc_s_modulator = fm_v4l2_vidioc_s_modulator
};
/* V4L2 RADIO device parent structure */
--
1.5.6.3
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [RFC/PATCH 8/8] drivers:staging:ti-st: Include FM TX module in Makefile
2010-09-02 15:57 ` [RFC/PATCH 7/8] drivers:staging:ti-st: Link FM TX module API with FM V4L2 module raja_mani
@ 2010-09-02 15:58 ` raja_mani
0 siblings, 0 replies; 12+ messages in thread
From: raja_mani @ 2010-09-02 15:58 UTC (permalink / raw)
To: hverkuil, linux-media, mchehab; +Cc: matti.j.aaltonen, Raja Mani
From: Raja Mani <raja_mani@ti.com>
Update Makefile to include FM TX module (fmdrv_tx) for
the compilation.
Signed-off-by: Raja Mani <raja_mani@ti.com>
---
drivers/staging/ti-st/Makefile | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/staging/ti-st/Makefile b/drivers/staging/ti-st/Makefile
index e6af3f1..bd29c83 100644
--- a/drivers/staging/ti-st/Makefile
+++ b/drivers/staging/ti-st/Makefile
@@ -6,4 +6,4 @@ obj-$(CONFIG_TI_ST) += st_drv.o
st_drv-objs := st_core.o st_kim.o st_ll.o
obj-$(CONFIG_ST_BT) += bt_drv.o
obj-$(CONFIG_ST_FM) += fm_drv.o
-fm_drv-objs := fmdrv_common.o fmdrv_rx.o fmdrv_v4l2.o
+fm_drv-objs := fmdrv_common.o fmdrv_rx.o fmdrv_tx.o fmdrv_v4l2.o
--
1.5.6.3
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [RFC/PATCH 1/8] drivers:media:video: Adding new CIDs for FM RX ctls
2010-09-02 15:57 ` [RFC/PATCH 1/8] drivers:media:video: Adding new CIDs for FM RX ctls raja_mani
2010-09-02 15:57 ` [RFC/PATCH 2/8] include:linux:videodev2: Define " raja_mani
@ 2010-09-08 20:11 ` Mauro Carvalho Chehab
1 sibling, 0 replies; 12+ messages in thread
From: Mauro Carvalho Chehab @ 2010-09-08 20:11 UTC (permalink / raw)
To: raja_mani; +Cc: hverkuil, linux-media, matti.j.aaltonen, Pramodh AG
Em 02-09-2010 12:57, raja_mani@ti.com escreveu:
> From: Raja Mani <raja_mani@ti.com>
>
> Add support for the following new Control IDs (CID)
> V4L2_CID_FM_RX_CLASS - FM RX Tuner controls
> V4L2_CID_FM_BAND - FM band
Hmm... both you and Matti are adding _the_same_ ioctls on different patchsets?
Please, coordinate between yourself to avoid duplicated/conflicted patches.
> V4L2_CID_RSSI_THRESHOLD - RSSI Threshold
> V4L2_CID_TUNE_AF - Alternative Frequency
>
> Signed-off-by: Raja Mani <raja_mani@ti.com>
> Signed-off-by: Pramodh AG <pramodh_ag@ti.com>
> ---
> drivers/media/video/v4l2-common.c | 16 ++++++++++++++++
> 1 files changed, 16 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
> index 4e53b0b..33c3037 100644
> --- a/drivers/media/video/v4l2-common.c
> +++ b/drivers/media/video/v4l2-common.c
> @@ -354,6 +354,12 @@ const char **v4l2_ctrl_get_menu(u32 id)
> "75 useconds",
> NULL,
> };
> + static const char *fm_band[] = {
> + "87.5 - 108. MHz",
> + "76. - 90. MHz, Japan",
> + "65. - 74. MHz, OIRT",
> + NULL,
> + };
Already NACKED at Matti's patchset. I'll review/comment the other ioctls together with the DocBook spec file.
>
> switch (id) {
> case V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ:
> @@ -394,6 +400,8 @@ const char **v4l2_ctrl_get_menu(u32 id)
> return colorfx;
> case V4L2_CID_TUNE_PREEMPHASIS:
> return tune_preemphasis;
> + case V4L2_CID_FM_BAND:
> + return fm_band;
> default:
> return NULL;
> }
> @@ -520,6 +528,10 @@ const char *v4l2_ctrl_get_name(u32 id)
> case V4L2_CID_TUNE_PREEMPHASIS: return "Pre-emphasis settings";
> case V4L2_CID_TUNE_POWER_LEVEL: return "Tune Power Level";
> case V4L2_CID_TUNE_ANTENNA_CAPACITOR: return "Tune Antenna Capacitor";
> + case V4L2_CID_FM_RX_CLASS: return "FM Radio Tuner Controls";
> + case V4L2_CID_FM_BAND: return "FM Band";
> + case V4L2_CID_RSSI_THRESHOLD: return "RSSI Threshold";
> + case V4L2_CID_TUNE_AF: return "Alternative Frequency";
>
> default:
> return NULL;
> @@ -585,6 +597,9 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste
> case V4L2_CID_EXPOSURE_AUTO:
> case V4L2_CID_COLORFX:
> case V4L2_CID_TUNE_PREEMPHASIS:
> + case V4L2_CID_FM_BAND:
> + case V4L2_CID_RSSI_THRESHOLD:
> + case V4L2_CID_TUNE_AF:
> qctrl->type = V4L2_CTRL_TYPE_MENU;
> step = 1;
> break;
> @@ -596,6 +611,7 @@ int v4l2_ctrl_query_fill(struct v4l2_queryctrl *qctrl, s32 min, s32 max, s32 ste
> case V4L2_CID_CAMERA_CLASS:
> case V4L2_CID_MPEG_CLASS:
> case V4L2_CID_FM_TX_CLASS:
> + case V4L2_CID_FM_RX_CLASS:
> qctrl->type = V4L2_CTRL_TYPE_CTRL_CLASS;
> qctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
> min = max = step = def = 0;
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [RFC/PATCH 2/8] include:linux:videodev2: Define new CIDs for FM RX ctls
2010-09-02 15:57 ` [RFC/PATCH 2/8] include:linux:videodev2: Define " raja_mani
2010-09-02 15:57 ` [RFC/PATCH 3/8] drivers:staging:ti-st: Sources for FM TX raja_mani
@ 2010-09-08 20:13 ` Mauro Carvalho Chehab
1 sibling, 0 replies; 12+ messages in thread
From: Mauro Carvalho Chehab @ 2010-09-08 20:13 UTC (permalink / raw)
To: raja_mani; +Cc: hverkuil, linux-media, matti.j.aaltonen, Pramodh AG
Em 02-09-2010 12:57, raja_mani@ti.com escreveu:
> From: Raja Mani <raja_mani@ti.com>
>
> Extend V4L2 CID list to support
> 1) FM RX Tuner controls
> 2) FM band
> 3) RSSI Threshold
> 4) Alternative Frequency
Hmm... no DocBooks for RSSI and "Alternative Frequency"... How do you expect me to review
new API additions if you aren't properly documenting and justifying the need for those
additions?
Cheers,
Mauro
>
> Signed-off-by: Raja Mani <raja_mani@ti.com>
> Signed-off-by: Pramodh AG <pramodh_ag@ti.com>
> ---
> include/linux/videodev2.h | 18 ++++++++++++++++++
> 1 files changed, 18 insertions(+), 0 deletions(-)
>
> diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
> index 7c99acf..2798137 100644
> --- a/include/linux/videodev2.h
> +++ b/include/linux/videodev2.h
> @@ -964,6 +964,7 @@ struct v4l2_writeback_ioctl_data {
> #define V4L2_CTRL_CLASS_MPEG 0x00990000 /* MPEG-compression controls */
> #define V4L2_CTRL_CLASS_CAMERA 0x009a0000 /* Camera class controls */
> #define V4L2_CTRL_CLASS_FM_TX 0x009b0000 /* FM Modulator control class */
> +#define V4L2_CTRL_CLASS_FM_RX 0x009c0000 /* FM Tuner control class */
>
> #define V4L2_CTRL_ID_MASK (0x0fffffff)
> #define V4L2_CTRL_ID2CLASS(id) ((id) & 0x0fff0000UL)
> @@ -1362,6 +1363,23 @@ enum v4l2_preemphasis {
> #define V4L2_CID_TUNE_POWER_LEVEL (V4L2_CID_FM_TX_CLASS_BASE + 113)
> #define V4L2_CID_TUNE_ANTENNA_CAPACITOR (V4L2_CID_FM_TX_CLASS_BASE + 114)
>
> +/* FM Tuner class control IDs */
> +#define V4L2_CID_FM_RX_CLASS_BASE (V4L2_CTRL_CLASS_FM_RX | 0x900)
> +#define V4L2_CID_FM_RX_CLASS (V4L2_CTRL_CLASS_FM_RX | 1)
> +
> +#define V4L2_CID_FM_BAND (V4L2_CID_FM_RX_CLASS_BASE + 1)
> +enum v4l2_fm_band {
> + V4L2_FM_BAND_OTHER = 0,
> + V4L2_FM_BAND_JAPAN = 1,
> + V4L2_FM_BAND_OIRT = 2
> +};
> +#define V4L2_CID_RSSI_THRESHOLD (V4L2_CID_FM_RX_CLASS_BASE + 2)
> +#define V4L2_CID_TUNE_AF (V4L2_CID_FM_RX_CLASS_BASE + 3)
> +enum v4l2_tune_af {
> + V4L2_FM_AF_OFF = 0,
> + V4L2_FM_AF_ON = 1
> +};
> +
> /*
> * T U N I N G
> */
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [RFC/PATCH 3/8] drivers:staging:ti-st: Sources for FM TX
2010-09-02 15:57 ` [RFC/PATCH 3/8] drivers:staging:ti-st: Sources for FM TX raja_mani
2010-09-02 15:57 ` [RFC/PATCH 4/8] drivers:staging:ti-st: Move get region func to FM RX module raja_mani
@ 2010-09-08 20:19 ` Mauro Carvalho Chehab
1 sibling, 0 replies; 12+ messages in thread
From: Mauro Carvalho Chehab @ 2010-09-08 20:19 UTC (permalink / raw)
To: raja_mani; +Cc: hverkuil, linux-media, matti.j.aaltonen, Pramodh AG
Em 02-09-2010 12:57, raja_mani@ti.com escreveu:
> From: Raja Mani <raja_mani@ti.com>
>
> This has implementation of FM TX functionality (for Wl127x and WL128x
> chip) which are listed below,
>
> 1) frequency set.
> 2) stereo/nono mode selection.
> 3) RDS config.
> 4) mute/unmute mode config.
> 5) power level config.
> 6) preemphasis filter config, etc.
>
> This will work on top of TI Shared Transport driver. It communicates with
> TI FM V4L2 module and TI FM Common module to perform the actual FM TX operation.
>
> Signed-off-by: Raja Mani <raja_mani@ti.com>
> Signed-off-by: Pramodh AG <pramodh_ag@ti.com>
> ---
> drivers/staging/ti-st/fmdrv_tx.c | 391 ++++++++++++++++++++++++++++++++++++++
> drivers/staging/ti-st/fmdrv_tx.h | 37 ++++
> 2 files changed, 428 insertions(+), 0 deletions(-)
> create mode 100644 drivers/staging/ti-st/fmdrv_tx.c
> create mode 100644 drivers/staging/ti-st/fmdrv_tx.h
>
> diff --git a/drivers/staging/ti-st/fmdrv_tx.c b/drivers/staging/ti-st/fmdrv_tx.c
> new file mode 100644
> index 0000000..55bf89a
> --- /dev/null
> +++ b/drivers/staging/ti-st/fmdrv_tx.c
> @@ -0,0 +1,391 @@
> +/*
> + * FM Driver for Connectivity chip of Texas Instruments.
> + * This sub-module of FM driver implements FM TX functionality.
> + *
> + * Copyright (C) 2010 Texas Instruments
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> + *
> + */
> +
> +#include <linux/delay.h>
> +#include "fmdrv.h"
> +#include "fmdrv_common.h"
> +#include "fmdrv_tx.h"
Where are those headers? Please send your patch series on an order that helps the
reviewers to understand the logic, sending first things first.
I'm not seeing the patches that are adding those include files, making hard to
understand the remaining patches of this series.
> +
> +int fm_tx_set_stereo_mono(struct fmdrv_ops *fmdev, unsigned short mode)
> +{
> + unsigned short payload;
> + int ret = 0;
> +
> + if (fmdev->curr_fmmode != FM_MODE_TX) {
> + ret = -EPERM;
> + goto exit;
> + }
> + if (fmdev->tx_data.aud_mode == mode)
> + goto exit;
> +
> + pr_debug("stereo mode: %d", (int)mode);
> +
> + /* Set Stereo/Mono mode */
> + FM_STORE_LE16_TO_BE16(payload, (1 - mode));
> + ret = fmc_send_cmd(fmdev, MONO_SET, &payload, sizeof(payload),
> + &fmdev->maintask_completion, NULL, NULL);
> + FM_CHECK_SEND_CMD_STATUS(ret);
> +
> + fmdev->tx_data.aud_mode = mode;
> +exit:
> + return ret;
> +}
> +
> +static int __set_rds_text(struct fmdrv_ops *fmdev, unsigned char *rds_text)
> +{
> + unsigned short payload;
> + int ret;
> +
> + ret = fmc_send_cmd(fmdev, RDS_DATA_SET, rds_text, strlen(rds_text),
> + &fmdev->maintask_completion, NULL, NULL);
> + FM_CHECK_SEND_CMD_STATUS(ret);
> +
> + /* Scroll mode */
> + FM_STORE_LE16_TO_BE16(payload, (unsigned short)0x1);
> + ret = fmc_send_cmd(fmdev, DISPLAY_MODE_SET, &payload, sizeof(payload),
> + &fmdev->maintask_completion, NULL, NULL);
> + FM_CHECK_SEND_CMD_STATUS(ret);
> +
> + return 0;
> +}
> +
> +static int __set_rds_data_mode(struct fmdrv_ops *fmdev, unsigned char mode)
> +{
> + unsigned short payload;
> + int ret;
> +
> + /* Setting unique PI TODO: how unique? */
> + FM_STORE_LE16_TO_BE16(payload, (unsigned short)0xcafe);
> + ret = fmc_send_cmd(fmdev, PI_SET, &payload, sizeof(payload),
> + &fmdev->maintask_completion, NULL, NULL);
> + FM_CHECK_SEND_CMD_STATUS(ret);
> +
> + /* Set decoder id */
> + FM_STORE_LE16_TO_BE16(payload, (unsigned short)0xa);
> + ret = fmc_send_cmd(fmdev, DI_SET, &payload, sizeof(payload),
> + &fmdev->maintask_completion, NULL, NULL);
> + FM_CHECK_SEND_CMD_STATUS(ret);
> +
> + /* TODO: RDS_MODE_GET? */
> + return 0;
> +}
> +
> +static int __set_rds_len(struct fmdrv_ops *fmdev, unsigned char type,
> + unsigned short len)
> +{
> + unsigned short payload;
> + int ret;
> +
> + len |= type << 8;
> + FM_STORE_LE16_TO_BE16(payload, len);
> + ret = fmc_send_cmd(fmdev, LENGHT_SET, &payload, sizeof(payload),
> + &fmdev->maintask_completion, NULL, NULL);
> +
> + FM_CHECK_SEND_CMD_STATUS(ret);
> +
> + /* TODO: LENGHT_GET? */
> + return 0;
> +}
> +
> +int fm_tx_set_rds_mode(struct fmdrv_ops *fmdev, unsigned char rds_en_dis)
> +{
> + unsigned short payload;
> + int ret;
> + unsigned char rds_text[] = "Zoom2\n";
> +
> + if (fmdev->curr_fmmode != FM_MODE_TX)
> + return -EPERM;
> +
> + pr_debug("rds_en_dis:%d(E:%d, D:%d)", rds_en_dis,
> + FM_RDS_ENABLE, FM_RDS_DISABLE);
> +
> + if (rds_en_dis == FM_RDS_ENABLE) {
> + /* Set RDS length */
> + __set_rds_len(fmdev, 0, strlen(rds_text));
> + /* Set RDS text */
> + __set_rds_text(fmdev, rds_text);
> + /* Set RDS mode */
> + __set_rds_data_mode(fmdev, 0x0);
> + }
> +
> + /* Send command to enable RDS */
> + if (rds_en_dis == FM_RDS_ENABLE)
> + FM_STORE_LE16_TO_BE16(payload, 0x01);
> + else
> + FM_STORE_LE16_TO_BE16(payload, 0x00);
> +
> + ret = fmc_send_cmd(fmdev, RDS_DATA_ENB, &payload, sizeof(payload),
> + &fmdev->maintask_completion, NULL, NULL);
> + FM_CHECK_SEND_CMD_STATUS(ret);
> +
> + if (rds_en_dis == FM_RDS_ENABLE) {
> + /* Set RDS length */
> + __set_rds_len(fmdev, 0, strlen(rds_text));
> + /* Set RDS text */
> + __set_rds_text(fmdev, rds_text);
> + }
> + fmdev->tx_data.rds.flag = rds_en_dis;
> +
> + return 0;
> +}
> +
> +int fm_tx_set_radio_text(struct fmdrv_ops *fmdev,
> + unsigned char *rds_text,
> + unsigned char rds_type)
> +{
> + unsigned short payload;
> + int ret;
> +
> + if (fmdev->curr_fmmode != FM_MODE_TX)
> + return -EPERM;
> +
> + fm_tx_set_rds_mode(fmdev, 0);
> + /* Set RDS length */
> + __set_rds_len(fmdev, rds_type, strlen(rds_text));
> + /* Set RDS text */
> + __set_rds_text(fmdev, rds_text);
> + /* Set RDS mode */
> + __set_rds_data_mode(fmdev, 0x0);
> +
> + FM_STORE_LE16_TO_BE16(payload, 1);
> + ret = fmc_send_cmd(fmdev, RDS_DATA_ENB, &payload, sizeof(payload),
> + &fmdev->maintask_completion, NULL, NULL);
> + FM_CHECK_SEND_CMD_STATUS(ret);
> +
> + return 0;
> +}
> +
> +int fm_tx_set_af(struct fmdrv_ops *fmdev, unsigned int af)
> +{
> + unsigned short payload;
> + int ret;
> +
> + if (fmdev->curr_fmmode != FM_MODE_TX)
> + return -EPERM;
> + pr_debug("AF: %d", af);
> +
> + af = (af - 87500) / 100;
> + FM_STORE_LE16_TO_BE16(payload, (unsigned short)af);
> + ret = fmc_send_cmd(fmdev, TA_SET, &payload, sizeof(payload),
> + &fmdev->maintask_completion, NULL, NULL);
> + FM_CHECK_SEND_CMD_STATUS(ret);
> + return 0;
> +}
> +
> +int fm_tx_set_region(struct fmdrv_ops *fmdev,
> + unsigned char region_to_set)
> +{
> + unsigned short payload;
> + int ret;
> +
> + if (region_to_set != FM_BAND_EUROPE_US &&
> + region_to_set != FM_BAND_JAPAN) {
> + pr_err("Invalid band\n");
> + return -EINVAL;
> + }
> +
> + /* Send command to set the band */
> + FM_STORE_LE16_TO_BE16(payload, (unsigned short)region_to_set);
> + ret = fmc_send_cmd(fmdev, TX_BAND_SET, &payload, sizeof(payload),
> + &fmdev->maintask_completion, NULL, NULL);
> + FM_CHECK_SEND_CMD_STATUS(ret);
> +
> + return 0;
> +}
> +
> +int fm_tx_set_mute_mode(struct fmdrv_ops *fmdev,
> + unsigned char mute_mode_toset)
> +{
> + unsigned short payload;
> + int ret;
> +
> + if (fmdev->curr_fmmode != FM_MODE_TX)
> + return -EPERM;
> + pr_debug("tx: mute mode %ld", (unsigned long)mute_mode_toset);
> +
> + FM_STORE_LE16_TO_BE16(payload, mute_mode_toset);
> + ret = fmc_send_cmd(fmdev, MUTE, &payload, sizeof(payload),
> + &fmdev->maintask_completion, NULL, NULL);
> + FM_CHECK_SEND_CMD_STATUS(ret);
> +
> + return 0;
> +}
> +
> +/* Set TX Audio I/O */
> +static int __set_audio_io(struct fmdrv_ops *fmdev)
> +{
> + struct fmtx_data *tx = &fmdev->tx_data;
> + unsigned short payload;
> + int ret;
> +
> + /* Set Audio I/O Enable */
> + FM_STORE_LE16_TO_BE16(payload, tx->audio_io);
> + ret = fmc_send_cmd(fmdev, AUDIO_IO_SET, &payload, sizeof(payload),
> + &fmdev->maintask_completion, NULL, NULL);
> + FM_CHECK_SEND_CMD_STATUS(ret);
> +
> + /* TODO: is audio set? */
> + return 0;
> +}
> +
> +/* Start TX Transmission */
> +static int __enable_xmit(struct fmdrv_ops *fmdev, unsigned char new_xmit_state)
> +{
> + struct fmtx_data *tx = &fmdev->tx_data;
> + unsigned short payload;
> + unsigned long timeleft;
> + int ret;
> +
> + /* Enable POWER_ENB interrupts */
> + FM_STORE_LE16_TO_BE16(payload, FM_POW_ENB_EVENT);
> + ret = fmc_send_cmd(fmdev, INT_MASK_SET, &payload, sizeof(payload),
> + &fmdev->maintask_completion, NULL, NULL);
> +
> + /* Set Power Enable */
> + FM_STORE_LE16_TO_BE16(payload, new_xmit_state);
> + ret = fmc_send_cmd(fmdev, POWER_ENB_SET, &payload, sizeof(payload),
> + &fmdev->maintask_completion, NULL, NULL);
> + FM_CHECK_SEND_CMD_STATUS(ret);
> +
> + /* Wait for Power Enabled */
> + init_completion(&fmdev->maintask_completion);
> + timeleft = wait_for_completion_timeout(&fmdev->maintask_completion,
> + FM_DRV_TX_TIMEOUT);
> + if (!timeleft) {
> + pr_err("Timeout(%d sec),didn't get tune ended interrupt",
> + jiffies_to_msecs(FM_DRV_TX_TIMEOUT) / 1000);
> + return -ETIMEDOUT;
> + }
> +
> + set_bit(FM_CORE_TX_XMITING, &fmdev->flag);
> + tx->xmit_state = new_xmit_state;
> +
> + return 0;
> +}
> +
> +/* Set TX power level */
> +int fm_tx_set_pwr_lvl(struct fmdrv_ops *fmdev, unsigned char new_pwr_lvl)
> +{
> + unsigned short payload;
> + struct fmtx_data *tx = &fmdev->tx_data;
> + int ret;
> +
> + if (fmdev->curr_fmmode != FM_MODE_TX)
> + return -EPERM;
> + pr_debug("tx: pwr_level_to_set %ld ", (long int)new_pwr_lvl);
> +
> + /* If the core isn't ready update global variable */
> + if (!test_bit(FM_CORE_READY, &fmdev->flag)) {
> + tx->pwr_lvl = new_pwr_lvl;
> + return 0;
> + }
> +
> + /* Set power level */
> + FM_STORE_LE16_TO_BE16(payload, new_pwr_lvl);
> + ret = fmc_send_cmd(fmdev, POWER_LEL_SET, &payload, sizeof(payload),
> + &fmdev->maintask_completion, NULL, NULL);
> + FM_CHECK_SEND_CMD_STATUS(ret);
> +
> + /* TODO: is the power level set? */
> + tx->pwr_lvl = new_pwr_lvl;
> +
> + return 0;
> +}
> +
> +/* Sets FM TX pre-emphasis filter value (OFF, 50us, or 75us)
> + * Convert V4L2 specified filter values to chip specific filter values.
> + */
> +int fm_tx_set_preemph_filter(struct fmdrv_ops *fmdev, unsigned int filter)
> +{
> + struct fmtx_data *tx = &fmdev->tx_data;
> + unsigned short payload;
> + int ret;
> +
> + if (fmdev->curr_fmmode != FM_MODE_TX)
> + return -EPERM;
> +
> + FM_STORE_LE16_TO_BE16(payload, filter);
> + ret = fmc_send_cmd(fmdev, PREMPH_SET, &payload, sizeof(payload),
> + &fmdev->maintask_completion, NULL, NULL);
> + FM_CHECK_SEND_CMD_STATUS(ret);
> +
> + tx->preemph = filter;
> + return ret;
> +}
> +
> +/* Sets FM TX antenna impedence value */
> +int fm_tx_set_ant_imp(struct fmdrv_ops *fmdev, unsigned char imp)
> +{
> + unsigned short payload;
> + int ret;
> +
> + if (fmdev->curr_fmmode != FM_MODE_TX)
> + return -EPERM;
> +
> + FM_STORE_LE16_TO_BE16(payload, imp);
> + ret = fmc_send_cmd(fmdev, IMP_SET, &payload, sizeof(payload),
> + &fmdev->maintask_completion, NULL, NULL);
> + FM_CHECK_SEND_CMD_STATUS(ret);
> +
> + return ret;
> +}
> +
> +/* Set TX Frequency */
> +int fm_tx_set_frequency(struct fmdrv_ops *fmdev, unsigned int freq_to_set)
> +{
> + struct fmtx_data *tx = &fmdev->tx_data;
> + unsigned short payload, chanl_index;
> + int ret;
> +
> + if (test_bit(FM_CORE_TX_XMITING, &fmdev->flag)) {
> + __enable_xmit(fmdev, 0);
> + clear_bit(FM_CORE_TX_XMITING, &fmdev->flag);
> + }
> +
> + /* Enable FR, BL interrupts */
> + FM_STORE_LE16_TO_BE16(payload, (FM_FR_EVENT | FM_BL_EVENT));
> + ret = fmc_send_cmd(fmdev, INT_MASK_SET, &payload, sizeof(payload),
> + &fmdev->maintask_completion, NULL, NULL);
> +
> + tx->tx_frq = (unsigned long)freq_to_set;
> + pr_debug("tx: freq_to_set %ld ", (long int)tx->tx_frq);
> +
> + chanl_index = freq_to_set / 10;
> + /* Set current tuner channel */
> + FM_STORE_LE16_TO_BE16(payload, chanl_index);
> + ret = fmc_send_cmd(fmdev, CHANL_SET, &payload, sizeof(payload),
> + &fmdev->maintask_completion, NULL, NULL);
> + FM_CHECK_SEND_CMD_STATUS(ret);
> +
> + fm_tx_set_pwr_lvl(fmdev, tx->pwr_lvl);
> + fm_tx_set_preemph_filter(fmdev, tx->preemph);
> +
> + tx->audio_io = 0x01; /* I2S */
> + __set_audio_io(fmdev);
> +
> + __enable_xmit(fmdev, 0x01); /* Enable transmission */
> +
> + tx->aud_mode = FM_STEREO_MODE;
> + tx->rds.flag = FM_RDS_DISABLE;
> +
> + return 0;
> +}
> +
> diff --git a/drivers/staging/ti-st/fmdrv_tx.h b/drivers/staging/ti-st/fmdrv_tx.h
> new file mode 100644
> index 0000000..f61dace
> --- /dev/null
> +++ b/drivers/staging/ti-st/fmdrv_tx.h
> @@ -0,0 +1,37 @@
> +/*
> + * FM Driver for Connectivity chip of Texas Instruments.
> + * FM TX module header.
> + *
> + * Copyright (C) 2010 Texas Instruments
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> + *
> + */
> +
> +#ifndef _FMDRV_TX_H
> +#define _FMDRV_TX_H
> +
> +int fm_tx_set_frequency(struct fmdrv_ops*, unsigned int);
> +int fm_tx_set_pwr_lvl(struct fmdrv_ops*, unsigned char);
> +int fm_tx_set_region(struct fmdrv_ops*, unsigned char);
> +int fm_tx_set_mute_mode(struct fmdrv_ops*, unsigned char);
> +int fm_tx_set_stereo_mono(struct fmdrv_ops*, unsigned short);
> +int fm_tx_set_rds_mode(struct fmdrv_ops*, unsigned char);
> +int fm_tx_set_radio_text(struct fmdrv_ops*, unsigned char*, unsigned char);
> +int fm_tx_set_af(struct fmdrv_ops*, unsigned int);
> +int fm_tx_set_preemph_filter(struct fmdrv_ops*, unsigned int);
> +int fm_tx_set_ant_imp(struct fmdrv_ops*, unsigned char);
> +
> +#endif
> +
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2010-09-08 20:19 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-09-02 15:57 [RFC/PATCH 0/8] Add FM TX support for TI WL127x and TI WL128x raja_mani
2010-09-02 15:57 ` [RFC/PATCH 1/8] drivers:media:video: Adding new CIDs for FM RX ctls raja_mani
2010-09-02 15:57 ` [RFC/PATCH 2/8] include:linux:videodev2: Define " raja_mani
2010-09-02 15:57 ` [RFC/PATCH 3/8] drivers:staging:ti-st: Sources for FM TX raja_mani
2010-09-02 15:57 ` [RFC/PATCH 4/8] drivers:staging:ti-st: Move get region func to FM RX module raja_mani
2010-09-02 15:57 ` [RFC/PATCH 5/8] drivers:staging:ti-st: Code cleanup in FM Common module raja_mani
2010-09-02 15:57 ` [RFC/PATCH 6/8] drivers:staging:ti-st: Extend FM TX global data structure raja_mani
2010-09-02 15:57 ` [RFC/PATCH 7/8] drivers:staging:ti-st: Link FM TX module API with FM V4L2 module raja_mani
2010-09-02 15:58 ` [RFC/PATCH 8/8] drivers:staging:ti-st: Include FM TX module in Makefile raja_mani
2010-09-08 20:19 ` [RFC/PATCH 3/8] drivers:staging:ti-st: Sources for FM TX Mauro Carvalho Chehab
2010-09-08 20:13 ` [RFC/PATCH 2/8] include:linux:videodev2: Define new CIDs for FM RX ctls Mauro Carvalho Chehab
2010-09-08 20:11 ` [RFC/PATCH 1/8] drivers:media:video: Adding " Mauro Carvalho Chehab
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).