radio: tavarua: Add IOCTL to enable the FM TX Tone generator

Implement IOCTL to set the Internal FM TX Tone
generator values

Change-Id: I2a94d5559a90362b9439ea510e98489102ed0c04
CRs-Fixed: 356789
Signed-off-by: Ayaz Ahmad <aahmad@codeaurora.org>
diff --git a/drivers/media/radio/radio-tavarua.c b/drivers/media/radio/radio-tavarua.c
index 6085871..a2993ce 100644
--- a/drivers/media/radio/radio-tavarua.c
+++ b/drivers/media/radio/radio-tavarua.c
@@ -996,6 +996,10 @@
 			FMDBG("read PHY_TXGAIN is successful");
 			complete(&radio->sync_req_done);
 			break;
+		case (XFR_EXT | 0x80):
+			FMDBG("Set tone generator successful\n");
+			complete(&radio->sync_req_done);
+			break;
 		case (0x80 | RX_CONFIG):
 		case (0x80 | RADIO_CONFIG):
 		case (0x80 | RDS_CONFIG):
@@ -3459,7 +3463,6 @@
 	case V4L2_CID_PRIVATE_SSBI_ACCS_ADDR:
 	case V4L2_CID_PRIVATE_SSBI_PEEK:
 	case V4L2_CID_PRIVATE_SSBI_POKE:
-	case V4L2_CID_PRIVATE_TX_TONE:
 	case V4L2_CID_PRIVATE_RDS_GRP_COUNTERS:
 	case V4L2_CID_PRIVATE_SET_NOTCH_FILTER:
 	case V4L2_CID_PRIVATE_TAVARUA_DO_CALIBRATION:
@@ -3479,6 +3482,54 @@
 	case V4L2_CID_PRIVATE_UPDATE_SPUR_TABLE:
 		retval = update_spur_table(radio);
 		break;
+	case V4L2_CID_PRIVATE_TX_TONE:
+		retval = 0;
+		memset(xfr_buf, 0, sizeof(xfr_buf));
+		switch (ctrl->value) {
+		case ONE_KHZ_LR_EQUA_0DBFS:
+			xfr_buf[TONE_CHANNEL_EN_AND_SCALING_BYTE]
+				= TONE_LEFT_RIGHT_CH_ENABLED;
+			xfr_buf[TONE_LEFT_FREQ_BYTE] = 0x01;
+			xfr_buf[TONE_RIGHT_FREQ_BYTE] = 0x01;
+			break;
+		case ONE_KHZ_LEFTONLY_EQUA_0DBFS:
+			xfr_buf[TONE_CHANNEL_EN_AND_SCALING_BYTE]
+				 = TONE_LEFT_CH_ENABLED;
+			xfr_buf[TONE_LEFT_FREQ_BYTE] = 0x01;
+			break;
+		case ONE_KHZ_RIGHTONLY_EQUA_0DBFS:
+			xfr_buf[TONE_CHANNEL_EN_AND_SCALING_BYTE]
+				 = TONE_RIGHT_CH_ENABLED;
+			xfr_buf[TONE_RIGHT_FREQ_BYTE] = 0x01;
+			break;
+		case ONE_KHZ_LR_EQUA_l8DBFS:
+			xfr_buf[TONE_CHANNEL_EN_AND_SCALING_BYTE]
+				 = (LSH_DATA(TONE_SCALE_IND_12,
+						 TONE_SCALING_SHIFT)
+					 | TONE_LEFT_RIGHT_CH_ENABLED);
+			xfr_buf[TONE_LEFT_FREQ_BYTE] = 0x01;
+			xfr_buf[TONE_RIGHT_FREQ_BYTE] = 0x01;
+			break;
+		case FIFTEEN_KHZ_LR_EQUA_l8DBFS:
+			xfr_buf[TONE_CHANNEL_EN_AND_SCALING_BYTE]
+				 = (LSH_DATA(TONE_SCALE_IND_12,
+						 TONE_SCALING_SHIFT)
+					 | TONE_LEFT_RIGHT_CH_ENABLED);
+			xfr_buf[TONE_LEFT_FREQ_BYTE] = 0x0F;
+			xfr_buf[TONE_RIGHT_FREQ_BYTE] = 0x0F;
+			break;
+		default:
+			retval = -1;
+			FMDERR("tone generator value not valid\n");
+			break;
+		}
+		if (retval >= 0) {
+			xfr_buf[TONE_GEN_CTRL_BYTE] = 0x01;
+			retval = sync_write_xfr(radio, XFR_EXT, xfr_buf);
+		}
+		if (retval < 0)
+			FMDERR("Tone generator failed\n");
+		break;
 	default:
 		retval = -EINVAL;
 	}
diff --git a/include/media/tavarua.h b/include/media/tavarua.h
index 9943287..adbdada 100644
--- a/include/media/tavarua.h
+++ b/include/media/tavarua.h
@@ -395,6 +395,22 @@
 
 #define	FM_TX_PWR_LVL_0		0 /* Lowest power lvl that can be set for Tx */
 #define	FM_TX_PWR_LVL_MAX	7 /* Max power lvl for Tx */
+
+/* Tone Generator control value */
+#define TONE_GEN_CTRL_BYTE		 0x00
+#define TONE_CHANNEL_EN_AND_SCALING_BYTE 0x01
+#define TONE_LEFT_FREQ_BYTE		 0x02
+#define TONE_RIGHT_FREQ_BYTE		 0x03
+#define TONE_LEFT_PHASE			 0x04
+#define TONE_RIGHT_PHASE		 0x05
+
+#define TONE_LEFT_CH_ENABLED		 0x01
+#define TONE_RIGHT_CH_ENABLED		 0x02
+#define TONE_LEFT_RIGHT_CH_ENABLED	 (TONE_LEFT_CH_ENABLED\
+						 | TONE_RIGHT_CH_ENABLED)
+
+#define TONE_SCALING_SHIFT		 0x02
+
 /* Transfer */
 enum tavarua_xfr_ctrl_t {
 	RDS_PS_0 = 0x01,
@@ -453,6 +469,7 @@
 	PHY_CONFIG,
 	PHY_TXBLOCK,
 	PHY_TCB,
+	XFR_EXT,
 	XFR_PEEK_MODE = 0x40,
 	XFR_POKE_MODE = 0xC0,
 	TAVARUA_XFR_CTRL_MAX
@@ -503,6 +520,7 @@
 	TWELVE_BYTE,
 	THIRTEEN_BYTE
 };
+
 #define XFR_READ		(0)
 #define XFR_WRITE		(1)
 #define XFR_MODE_OFFSET		(0)
@@ -531,4 +549,28 @@
 	__u8   data[XFR_REG_NUM];
 } __packed;
 
+enum Internal_tone_gen_vals {
+	ONE_KHZ_LR_EQUA_0DBFS = 1,
+	ONE_KHZ_LEFTONLY_EQUA_0DBFS,
+	ONE_KHZ_RIGHTONLY_EQUA_0DBFS,
+	ONE_KHZ_LR_EQUA_l8DBFS,
+	FIFTEEN_KHZ_LR_EQUA_l8DBFS
+};
+
+enum Tone_scaling_indexes {
+	TONE_SCALE_IND_0,
+	TONE_SCALE_IND_1,
+	TONE_SCALE_IND_2,
+	TONE_SCALE_IND_3,
+	TONE_SCALE_IND_4,
+	TONE_SCALE_IND_5,
+	TONE_SCALE_IND_6,
+	TONE_SCALE_IND_7,
+	TONE_SCALE_IND_8,
+	TONE_SCALE_IND_9,
+	TONE_SCALE_IND_10,
+	TONE_SCALE_IND_11,
+	TONE_SCALE_IND_12
+};
+
 #endif /* __LINUX_TAVARUA_H */