aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStuart MacDonald <stuart.macdonald@stericsson.com>2010-05-26 09:30:40 +0200
committerJohn Rigby <john.rigby@linaro.org>2010-09-02 22:45:25 -0600
commit39607c005bca3ebb8f846cca12dcfcbc631fd0bf (patch)
tree5fa91ddaef826a28cd72fdf4c6cd8ce0fc503914
parentfd68b76d27bb82c65bdeb6cf35d2dfc295427379 (diff)
FM Radio: Integration of CG2900 FM driver
This change updates the driver, documentation, and firmware files for the CG2900 FM radio driver. ST-Ericsson Change-ID: 259611 Change-Id: I95f9cb6b6944bcfe268ac1f442553a3ec72c32ee
-rw-r--r--[-rwxr-xr-x]Documentation/DocBook/ste_fm_radio.tmpl523
-rwxr-xr-xdrivers/media/radio/CG2900/fmdriver.c3804
-rwxr-xr-xdrivers/media/radio/CG2900/fmdriver.h1400
-rwxr-xr-xdrivers/media/radio/CG2900/platformosapi.c246
-rwxr-xr-xdrivers/media/radio/CG2900/platformosapi.h37
-rwxr-xr-xdrivers/media/radio/CG2900/radio-CG2900.c2408
-rwxr-xr-xdrivers/media/radio/CG2900/stefmapi.c3573
-rwxr-xr-xdrivers/media/radio/CG2900/stefmapi.h699
-rwxr-xr-xfirmware/BT_src_coeff_1.1.fw.org (renamed from firmware/R1e2v10BT_src_coeff_11.fw.org)bin2056 -> 2056 bytes
-rwxr-xr-xfirmware/Cobra_FM_SOC1_coef.fw.orgbin0 -> 3086 bytes
-rwxr-xr-xfirmware/Cobra_FM_SOC1_prog.fw.orgbin0 -> 48176 bytes
-rwxr-xr-xfirmware/EXT_src_coeff_1.1.fw.org (renamed from firmware/R1e2v10EXT_src_coeff_11.fw.org)bin2056 -> 2056 bytes
-rw-r--r--firmware/Makefile4
-rwxr-xr-xfirmware/R1e2v10FM_coeff.fw.orgbin2890 -> 0 bytes
-rwxr-xr-xfirmware/R1e2v10FM_prog.fw.orgbin35282 -> 0 bytes
-rw-r--r--[-rwxr-xr-x]firmware/ste_fm_bt_src_coeff_info.fw.org16
-rw-r--r--[-rwxr-xr-x]firmware/ste_fm_ext_src_coeff_info.fw.org16
-rw-r--r--[-rwxr-xr-x]firmware/ste_fm_fm_coeff_info.fw.org14
-rw-r--r--[-rwxr-xr-x]firmware/ste_fm_fm_prog_info.fw.org14
19 files changed, 7766 insertions, 4988 deletions
diff --git a/Documentation/DocBook/ste_fm_radio.tmpl b/Documentation/DocBook/ste_fm_radio.tmpl
index 98c20b8ce22..41f690ee03a 100755..100644
--- a/Documentation/DocBook/ste_fm_radio.tmpl
+++ b/Documentation/DocBook/ste_fm_radio.tmpl
@@ -160,7 +160,7 @@
<term>Switching On FM</term>
<listitem>
<para>
- For switching on FM the character device /dev/radio0 should be opened from user space.
+ To switch on the FM the character device, /dev/radio0 should be opened from user space. This sets the FM Radio to Idle mode. To configure the FM Radio in Rx or Tx mode use the IOCTL's VIDIOC_S_TUNER and VIDIOC_S_MODULATOR respectively.
<programlisting>
int fd;
@@ -190,7 +190,7 @@
<term>Switching Off FM</term>
<listitem>
<para>
- For switching on FM the character device /dev/radio0 should be opened from user space.
+ To switch on the FM the character device /dev/radio0 should be opened from user space.
<programlisting>
if(fd &gt;= 0)
@@ -203,6 +203,66 @@
</variablelist>
</section>
+ <section id="Rx-Mode">
+ <title>Switching To FM Rx Mode</title>
+ <para>
+ <!-- TODO: Describe parameters that can be specified at kernel
+ driver loading with insmod or modprobe. If the driver
+ has no parameters to be specified at load time, replace this
+ text with "Not Applicable". -->
+ </para>
+ <variablelist>
+ <varlistentry>
+ <term>Switching To FM Rx Mode</term>
+ <listitem>
+ <para>
+ To switch on the FM Rx mode the IOCTL VIDIOC_S_TUNER should be called with appropriate parameters.
+ <programlisting>
+
+ memset(&amp;tuner, 0, sizeof(tuner));
+ tuner.index = 0;
+ tuner.rxsubchans |= V4L2_TUNER_SUB_STEREO;
+ if (ioctl(fd, VIDIOC_S_TUNER, &amp;tuner) &lt; 0) {
+ printf("VIDIOC_S_TUNER:error!!\n");
+ return;
+
+ </programlisting>
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </section>
+
+ <section id="Tx-Mode">
+ <title>Switching To FM Tx Mode</title>
+ <para>
+ <!-- TODO: Describe parameters that can be specified at kernel
+ driver loading with insmod or modprobe. If the driver
+ has no parameters to be specified at load time, replace this
+ text with "Not Applicable". -->
+ </para>
+ <variablelist>
+ <varlistentry>
+ <term>Switching To FM Tx Mode</term>
+ <listitem>
+ <para>
+ To switch on the FM Tx mode the IOCTL VIDIOC_S_MODULATOR should be called with appropriate parameters.
+ <programlisting>
+
+ memset(&amp;modulator, 0, sizeof(modulator));
+ modulator.index = 0;
+ modulator.txsubchans |= V4L2_TUNER_SUB_STEREO;
+ if (ioctl(fd, VIDIOC_S_MODULATOR, &amp;modulator) &lt; 0) {
+ printf("VIDIOC_S_MODULATOR:error!!\n");
+ return;
+
+ </programlisting>
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </section>
+
<section id="FM-Standby">
<title>Standby</title>
<para>
@@ -213,17 +273,17 @@
</para>
<variablelist>
<varlistentry>
- <term>Making the FM Radio go in Standby Mode</term>
+ <term>Making the FM Radio go into Standby Mode</term>
<listitem>
<para>
- For making the FM Radio go in Standby mode, the IOCLT VIDIOC_S_CTRL should be used. The id of the v4l2_control structure should be set to V4L2_CID_CG2900_RADIO_CHIP_STATE and the value of v4l2_control structure should be set as V4L2_CG2900_RADIO_STANDBY.
+ To make the FM Radio go in Standby mode, the IOCTL VIDIOC_S_CTRL should be used. The id of the v4l2_control structure should be set to V4L2_CID_CG2900_RADIO_CHIP_STATE and the value of v4l2_control structure should be set as V4L2_CG2900_RADIO_STANDBY.
<programlisting>
struct v4l2_control sctrl;
int ret;
sctrl.id = V4L2_CID_CG2900_RADIO_CHIP_STATE;
sctrl.value = V4L2_CG2900_RADIO_STANDBY;
- ret = ioctl(fd, VIDIOC_S_CTRL, &amp; sctrl);
+ ret = ioctl(fd, VIDIOC_S_CTRL, &amp;sctrl);
if (ret &lt; 0) {
printf("VIDIOC_S_CTRL:error!!\n");
}
@@ -247,14 +307,14 @@
<term>Powering Up FM Radio from Standby Mode</term>
<listitem>
<para>
- For powering up FM radio again from standby mode, the IOCLT VIDIOC_S_CTRL should be used. The id of the v4l2_control structure should be set to V4L2_CID_CG2900_RADIO_CHIP_STATE and the value of v4l2_control structure should be set as V4L2_CG2900_RADIO_POWERUP.
+ To power up the FM radio from standby mode, the IOCTL VIDIOC_S_CTRL should be used. The id of the v4l2_control structure should be set to V4L2_CID_CG2900_RADIO_CHIP_STATE and the value of v4l2_control structure should be set as V4L2_CG2900_RADIO_POWERUP.
<programlisting>
struct v4l2_control sctrl;
int ret;
sctrl.id = V4L2_CID_CG2900_RADIO_CHIP_STATE;
sctrl.value = V4L2_CG2900_RADIO_POWERUP;
- ret = ioctl(fd, VIDIOC_S_CTRL, &amp; sctrl);
+ ret = ioctl(fd, VIDIOC_S_CTRL, &amp;sctrl);
if (ret &lt; 0) {
printf("VIDIOC_S_CTRL:error!!\n");
}
@@ -278,14 +338,14 @@
<term>Tune to a particular station</term>
<listitem>
<para>
- for tuning to a particular station, the IOCLT VIDIOC_S_FREQUENCY should be used. The frequency of the v4l2_frequency structure should be converted to V4L2 format.
+ To tune to a particular station, the IOCTL VIDIOC_S_FREQUENCY should be used. The frequency of the v4l2_frequency structure should be converted to V4L2 format.
<programlisting>
struct v4l2_frequency freq;
int ret;
/* Convert frequency in Hz to V4L2 Format */
freq.frequency = (frequency * 2)/ 125;
- ret = ioctl(fd, VIDIOC_S_FREQUENCY, &amp; freq);
+ ret = ioctl(fd, VIDIOC_S_FREQUENCY, &amp;freq);
if (ret &lt; 0) {
printf("VIDIOC_S_FREQUENCY:error!!\n");
}
@@ -309,12 +369,12 @@
<term>Get the Currently tuned Station Frequncy</term>
<listitem>
<para>
- for tuning to a particular station, the IOCLT VIDIOC_G_FREQUENCY should be used. The frequency returened in the v4l2_frequency structure would be in V4L2 format.
+ To tune to a particular station, the IOCTL VIDIOC_G_FREQUENCY should be used. The frequency returned in the v4l2_frequency structure will be in V4L2 format.
<programlisting>
struct v4l2_frequency freq;
int ret;
- ret = ioctl(fd, VIDIOC_G_FREQUENCY, &amp; freq);
+ ret = ioctl(fd, VIDIOC_G_FREQUENCY, &amp;freq);
if (ret &lt; 0) {
printf("VIDIOC_G_FREQUENCY:error!!\n");
*frequency = 0;
@@ -329,8 +389,8 @@
</variablelist>
</section>
- <section id="seek-up-down">
- <title>Seek</title>
+ <section id="get-signal-strength">
+ <title>Retreive Signal Strength</title>
<para>
<!-- TODO: Describe parameters that can be specified at kernel
driver loading with insmod or modprobe. If the driver
@@ -339,32 +399,25 @@
</para>
<variablelist>
<varlistentry>
- <term>Seek Up/Down</term>
+ <term>Retreive Signal Strength</term>
<listitem>
<para>
- For searching next available channel in upward or downward direction, IOCTL VIDIOC_S_HW_FREQ_SEEK should be used with parameter seek_upward of v4l2_hw_freq_seek structure be filled with direct of search. For searching upwards use 1 and for searching downwards use 0 as the value respectively. If the IOCTL returns successfully, a thread should be created to start polling to FM driver, to wait till search is complete. When poll is complete, the tuned frequency should be retrived from FM Driver by using the IOCTL VIDIOC_G_FREQUENCY.
+ To retreive the signal strength of the currently tuned channel in FM Rx mode, IOCTL VIDIOC_G_TUNER should be called. The current signal strength would be represented by the parameter signal of the v4l2_tuner structure.
<programlisting>
- void search()
+ void get_signal_strength(int *rssi)
{
- struct v4l2_hw_freq_seek seek;
+ struct v4l2_tuner tuner;
int ret;
- if(1 == direction) {
- seek.seek_upward = 1;
- }
- else if(0 == direction) {
- seek.seek_upward = 0;
- }
- else {
- printf("Invalid direction = %d\n", direction);
- return;
- }
- seek.wrap_around = 0;
- ret = ioctl(fd, VIDIOC_S_HW_FREQ_SEEK, &amp; seek);
+ memset(&amp;tuner, 0, sizeof(tuner));
+ tuner.index = 0;
+ ret = ioctl(fd, VIDIOC_G_TUNER, &amp;tuner);
if (ret &lt; 0) {
- printf("VIDIOC_S_HW_FREQ_SEEK:error!!\n");
+ printf("VIDIOC_G_TUNER:error!!\n");
+ *rssi = 0;
return;
}
+ *rssi = tuner.signal;
}
</programlisting>
</para>
@@ -386,7 +439,7 @@
<term>Band Scan</term>
<listitem>
<para>
- For doing a band scan, ie search for all available stations in the entire FM band, IOCTL VIDIOC_S_CTRL should be used with parameter id of the v4l2_control structure should be set to V4L2_CID_CG2900_RADIO_BANDSCAN and the value of v4l2_control structure should be set as V4L2_CG2900_RADIO_BANDSCAN_START. If the IOCTL returns successfully, a thread should be created to start polling to FM driver, to wait till scan is complete. When poll is complete, the found stations along with RSSI should be retrived using the IOCTL VIDIOC_G_EXT_CTRLS should be used with parameters as described in example code.
+ To conduct a band scan, which searches for all available stations in the entire FM band, IOCTL VIDIOC_S_CTRL should be used with parameter id of the v4l2_control structure should be set to V4L2_CID_CG2900_RADIO_BANDSCAN and the value of v4l2_control structure should be set as V4L2_CG2900_RADIO_BANDSCAN_START. If the IOCTL returns successfully, a thread should be created to start polling to FM driver, to wait till scan is complete. When poll is complete, the found stations along with RSSI should be retrived using the IOCTL VIDIOC_G_EXT_CTRLS should be used with parameters as described in example code.
<programlisting>
void scan()
{
@@ -396,11 +449,11 @@
sctrl.id = V4L2_CID_CG2900_RADIO_BANDSCAN;
sctrl.value = V4L2_CG2900_RADIO_BANDSCAN_START;
- ret = ioctl(fd, VIDIOC_S_CTRL, &amp; sctrl);
+ ret = ioctl(fd, VIDIOC_S_CTRL, &amp;sctrl);
if (ret &lt; 0) {
printf("VIDIOC_S_CTRL:error!!\n");
}
- pthread_create(&amp; fmScanThread, NULL, FmScanThread, NULL);
+ pthread_create(&amp;fmScanThread, NULL, FmScanThread, NULL);
}
static void *FmScanThread(void *param)
{
@@ -412,20 +465,22 @@
pollFd.fd = fd;
pollFd.events = POLLRDBAND;
- ret = poll(&amp; pollFd, 1, 1000);
+ ret = poll(&amp;pollFd, 1, 1000);
- if(pollFd.revents &amp; POLLRDBAND)
+ if(ret)
{
- /* Get the Number OF Channels */
- scanResult.count = 0;
- scanResult.ctrl_class = V4L2_CTRL_CLASS_USER;
- scanResult.controls = (struct v4l2_ext_control *) malloc(sizeof(struct v4l2_ext_control));
- scanResult.controls->id = V4L2_CID_CG2900_RADIO_BANDSCAN_GET_RESULTS;
- scanResult.controls->size = 0;
- scanResult.controls->string = NULL;
- err = ioctl(fd, VIDIOC_G_EXT_CTRLS, &amp; scanResult);
-
- if (err &lt; 0 &amp; &amp; errno != ENOSPC) {
+ if(pollFd.revents &amp; POLLRDBAND)
+ {
+ /* Get the Number OF Channels */
+ scanResult.count = 0;
+ scanResult.ctrl_class = V4L2_CTRL_CLASS_USER;
+ scanResult.controls = (struct v4l2_ext_control *) malloc(sizeof(struct v4l2_ext_control));
+ scanResult.controls->id = V4L2_CID_CG2900_RADIO_BANDSCAN_GET_RESULTS;
+ scanResult.controls->size = 0;
+ scanResult.controls->string = NULL;
+ err = ioctl(fd, VIDIOC_G_EXT_CTRLS, &amp; scanResult);
+
+ if (err &lt; 0 &amp; &amp; errno != ENOSPC) {
printf("VIDIOC_G_EXT_CTRLS:error!!\n");
goto err;
}
@@ -436,25 +491,27 @@
p = scanResult.controls->string;
printf("\nNumber of Channels Found = %d \n", scanResult.controls->size);
/* Retrieve the Data now */
- ret = ioctl(fd, VIDIOC_G_EXT_CTRLS, &amp; scanResult);
+ ret = ioctl(fd, VIDIOC_G_EXT_CTRLS, &amp;scanResult);
if (ret &lt; 0) {
printf("VIDIOC_G_EXT_CTRLS:error!!\n");
goto err;
}
for (index = 0, count = 0; index &lt; scanResult.controls->size; index ++, count +=2) {
- printf("%d %d.%d %d\n", index + 1, MEGAHRTZ((*(p +count + 0) * 125) / 2), *(p + count + 1));
+ printf("%d %d.%d %d\n", index + 1, MEGAHRTZ((*(p +count + 0) * 125) / 2), *(p + count + 1));
}
err:
free(p);
free(scanResult.controls);
}
+ else if( pollFd.revents &amp; POLLHUP)
+ {
+ printf("\nScan Cancelled By User!!\n");
+ }
+ free(scanResult.controls);
}
- else if( pollFd.revents &amp; POLLHUP)
- {
- printf("\nScan Cancelled By User!!\n");
- }
- else if( pollFd.revents &amp; POLLERR){
- printf("\nError in Scaning, Timeout!!!\n");
+
+ else if( ret == 0){
+ printf("\nError in Scanning, Timeout!!!\n");
}
return 0;
}
@@ -479,7 +536,7 @@
<term>Cancel Scan/Seek</term>
<listitem>
<para>
- For cancelling an ongoing Band Scan or Seek, IOCTL VIDIOC_S_CTRL should be used with parameter id of the v4l2_control structure should be set to V4L2_CID_CG2900_RADIO_BANDSCAN and the value of v4l2_control structure should be set as V4L2_CG2900_RADIO_BANDSCAN_STOP.
+ To cancell an ongoing Band Scan or Seek, IOCTL VIDIOC_S_CTRL should be used with parameter id of the v4l2_control structure should be set to V4L2_CID_CG2900_RADIO_BANDSCAN and the value of v4l2_control structure should be set as V4L2_CG2900_RADIO_BANDSCAN_STOP.
<programlisting>
struct v4l2_control sctrl;
int ret;
@@ -487,7 +544,7 @@
sctrl.id = V4L2_CID_CG2900_RADIO_BANDSCAN;
sctrl.value = V4L2_CG2900_RADIO_BANDSCAN_STOP;
- ret = ioctl(fd, VIDIOC_S_CTRL, &amp; sctrl);
+ ret = ioctl(fd, VIDIOC_S_CTRL, &amp;sctrl);
if (ret &lt; 0) {
printf("VIDIOC_S_CTRL:error!!\n");
}
@@ -508,29 +565,271 @@
</para>
<variablelist>
<varlistentry>
- <term>Receive RDS Data</term>
+ <term>RDS Receive</term>
<listitem>
<para>
- By default rds is disabled in FM driver, IOCTL VIDIOC_S_CTRL should be used with parameter id of the v4l2_control structure should be set to V4L2_CID_CG2900_RADIO_RDS_STATE and the value of v4l2_control structure should be set as V4L2_CG2900_RADIO_RDS_ON if rds needs to be enabled and V4L2_CG2900_RADIO_RDS_OFF in case rds is to be disabled. A thread should be created and read() should be called to receive RDS data from driver. The RDS data received from FM Driver should be parsed in user space to retrive RDS information.
+ To enable or disable RDS for FM Rx, IOCTL VIDIOC_S_TUNER should be used with parameter rxsubchans of the v4l2_tuner structure set to V4L2_TUNER_SUB_RDS if rds needs to be enabled and the same value must not be set in case rds is to be disabled. A thread should be created and read() should be called to receive RDS data from driver. The RDS data received from FM Driver should be parsed in user space to retrive RDS information i.e Radio Text, Program Service Name, Program Identification, Program Type, Alternate Frequency, etc.
<programlisting>
- struct v4l2_control sctrl;
+ void rds_rx_set(bool enable_rds)
+ {
+ struct v4l2_tuner tuner;
int ret;
- sctrl.id = V4L2_CID_CG2900_RADIO_RDS_STATE;
- sctrl.value = V4L2_CG2900_RADIO_RDS_ON; // or V4L2_CG2900_RADIO_RDS_OFF
+ memset(&amp;tuner, 0, sizeof(tuner));
+ tuner.index = 0;
+ if(enable_rds)
+ tuner.rxsubchans |= V4L2_TUNER_SUB_RDS;
+ else
+ tuner.rxsubchans &amp; = ~V4L2_TUNER_SUB_RDS;
+ ret = ioctl(fd, VIDIOC_S_TUNER, &amp;tuner);
+ if (ret &lt; 0) {
+ printf("VIDIOC_S_TUNER:error!!\n");
+ }
+ }
+ </programlisting>
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </section>
+
+ <section id="af-update_switch">
+ <title>AF Update and Switching</title>
+ <para>
+ <!-- TODO: Describe parameters that can be specified at kernel
+ driver loading with insmod or modprobe. If the driver
+ has no parameters to be specified at load time, replace this
+ text with "Not Applicable". -->
+ </para>
+ <variablelist>
+ <varlistentry>
+ <term>AF Update &amp; Switching</term>
+ <listitem>
+
+ <para>Alternate Frequency (AF) Handling needs to be done in user space.
+ </para>
+ <para>The application should use the AF RDS group data to compose a list of AFs when tuned to a new channel.
+ </para>
+ <para>When the reception of the currently tuned frequency falls below a set threshold, it can decide to switch to one of the alternative frequencies for this channel.
+ </para>
+ <para>The application can perform an AF Update, which returns the RSSI value for all or some of the channel's AFs. Thus allowing the hardware to switch to the AF with the highest RSSI. The AF Update could be designed to stop as soon as it finds an AF with an acceptable RSSI level. In the event that all the AF RSSI values are lower than the base channel, the AF Switch would not be necessary.
+ </para>
+ <para>To know the RSSI of the alternative frequencies, the application can use the IOCTL VIDIOC_S_CTRL with parameter id set to V4L2_CID_CG2900_RADIO_RDS_AF_UPDATE_START, and the parameter value be set as the frequency in Hz for a channel from the AF List. If this call returns successfully, the RSSI of the frequency can then be retrieved. Using IOCTL VIDIOC_G_CTRL, with the parameter id set to V4L2_CID_CG2900_RADIO_RDS_AF_UPDATE_GET_RESULT, and the output parameter value will contain the RSSI of the AF frequency.
+ </para>
+ <para>If it is still deemed necessary to switch channels, the next step is then to switch to an alternative frequency in the AF list. This can be done using the IOCTL VIDIOC_S_EXT_CTRLS, with:
+ </para>
+ <itemizedlist>
+
+ <listitem><para>Parameter id set to V4L2_CID_CG2900_RADIO_RDS_AF_SWITCH_START</para></listitem>
+ <listitem><para>Parameter size set to 2</para></listitem>
+ <listitem><para>Parameters filled as below (string field of the parameter) </para></listitem>
+ <listitem><para>Control class parameter set to V4L2_CTRL_CLASS_USER</para></listitem>
+ <listitem><para>The AF switch frequency in Hz</para></listitem>
+ <listitem><para>Expected PI code </para></listitem>
+ </itemizedlist>
+ <para>The application can check if the AF switch succeeded or not using the IOCTL VIDIOC_G_CTRL, with parameter id set to V4L2_CID_CG2900_RADIO_RDS_AF_SWITCH_GET_RESULT, and the output parameter value will contain the AF switch conclusion.
+ </para>
+
+ <para> The example code below illustrates both the aforementioned functionalities.
+ </para>
+ <para>
+
+ <programlisting>
+ void PerformAFUpdate(long AF_Frequency, int *AF_Rssi)
+ {
+ struct v4l2_control sctrl, gctrl;
+ int ret;
+
+ sctrl.id = V4L2_CID_CG2900_RADIO_RDS_AF_UPDATE_START;
+ sctrl.value = AF_Frequency;
ret = ioctl(fd, VIDIOC_S_CTRL, &amp; sctrl);
if (ret &lt; 0) {
printf("VIDIOC_S_CTRL:error!!\n");
}
+ gctrl.id = V4L2_CID_CG2900_RADIO_RDS_AF_UPDATE_GET_RESULT;
+ ret = ioctl(fd, VIDIOC_G_CTRL, &amp; gctrl);
+ if (ret &lt; 0) {
+ printf("VIDIOC_G_CTRL:error!!\n");
+ }
+ *AF_Rssi = gctrl.value;
+ }
+ void PerformAFSwitch(long AF_BestFrequency, int AF_ExpectedPI, int *AF_SwitchConclusion)
+ {
+ struct v4l2_control gctrl;
+ struct v4l2_ext_controls ext_ctrl;
+ int ret;
+
+ int conclusion;
+ long freq;
+ long *p = NULL;
+
+ ext_ctrl.ctrl_class = V4L2_CTRL_CLASS_USER;
+ ext_ctrl.controls = (struct v4l2_ext_control *) malloc(sizeof(struct v4l2_ext_control));
+
+ ext_ctrl.count = 0;
+ ext_ctrl.controls->id = V4L2_CID_CG2900_RADIO_RDS_AF_SWITCH_START;
+ ext_ctrl.controls->size = 2;
+ ext_ctrl.controls->string = (long *)malloc(sizeof(long) * ext_ctrl.controls->size);
+ p = ext_ctrl.controls->string;
+ memcpy(p, &amp; AF_BestFrequency, sizeof(long));
+ memcpy(p + sizeof(long), &amp; AF_ExpectedPI, sizeof(int));
+
+
+ ret = ioctl(fd, VIDIOC_S_EXT_CTRLS, &amp; ext_ctrl);
+ if (ret &lt; 0) {
+ printf("VIDIOC_S_EXT_CTRLS:error!!\n");
+ }
+ free(ext_ctrl.controls->string);
+ free(ext_ctrl.controls);
+
+ gctrl.id = V4L2_CID_CG2900_RADIO_RDS_AF_SWITCH_GET_RESULT;
+ ret = ioctl(fd, VIDIOC_G_CTRL, &amp; gctrl);
+ if (ret &lt; 0) {
+ printf("VIDIOC_G_CTRL:error!!\n");
+ }
+ *AF_SwitchConclusion = gctrl.value;
+ }
</programlisting>
</para>
</listitem>
</varlistentry>
</variablelist>
</section>
- </chapter>
+ <section id="rds-transmit">
+ <title>RDS Transmit</title>
+ <para>
+ <!-- TODO: Describe parameters that can be specified at kernel
+ driver loading with insmod or modprobe. If the driver
+ has no parameters to be specified at load time, replace this
+ text with "Not Applicable". -->
+ </para>
+ <variablelist>
+ <varlistentry>
+ <term>RDS Transmit</term>
+ <listitem>
+ <para>
+ To enable or disable RDS during FM Tx, IOCTL VIDIOC_S_MODULATOR should be used with parameter txsubchans of the v4l2_modulator structure set to V4L2_TUNER_SUB_RDS if rds needs to be enabled and the same value must not be set in case rds is to be disabled. For Trasmitting RDS Data like PI, PTY, PSN, RT, VIDIOC_S_EXT_CTRLS IOCTL should be used with the id set to V4L2_CID_RDS_TX_PI, V4L2_CID_RDS_TX_PTY, V4L2_CID_RDS_TX_PS_NAME and V4L2_CID_RDS_TX_RADIO_TEXT respectively. Below example shows how to transmit various RDS functionalities.
+ <programlisting>
+ void rds_tx_set(bool enable_rds)
+ {
+ struct v4l2_modulator modulator;
+ int ret;
+
+ memset(&amp;modulator, 0, sizeof(modulator));
+ modulator.index = 0;
+ if(enable_rds)
+ modulator.txsubchans |= V4L2_TUNER_SUB_RDS;
+ else
+ modulator.txsubchans &amp; = ~V4L2_TUNER_SUB_RDS;
+ ret = ioctl(fd, VIDIOC_S_MODULATOR, &amp; modulator);
+ if (ret &lt; 0) {
+ printf("VIDIOC_S_MODULATOR:error!!\n");
+ }
+ }
+ void rds_tx_PI(void *value)
+ {
+ struct v4l2_ext_controls ext_ctrl;
+ int ret;
+ unsigned short *pi_code = (unsigned short *)value;
+
+ ext_ctrl.ctrl_class = V4L2_CTRL_CLASS_FM_TX;
+ ext_ctrl.controls = (struct v4l2_ext_control *) malloc(sizeof(struct v4l2_ext_control));
+
+
+ ext_ctrl.count = 0;
+ ext_ctrl.controls->id = V4L2_CID_RDS_TX_PI;
+ ext_ctrl.controls->size = 0;
+ ext_ctrl.controls->string = NULL;
+ ext_ctrl.controls->value = *pi_code;
+
+ ret = ioctl(fd, VIDIOC_S_EXT_CTRLS, &amp; ext_ctrl);
+ if (ret &lt; 0) {
+ printf("VIDIOC_S_EXT_CTRLS:error!!\n");
+ }
+ free(ext_ctrl.controls);
+ }
+ void rds_tx_PTY(void *value)
+ {
+ struct v4l2_ext_controls ext_ctrl;
+ int ret;
+ unsigned short *pty_code = (unsigned short *)value;
+
+ ext_ctrl.ctrl_class = V4L2_CTRL_CLASS_FM_TX;
+ ext_ctrl.controls = (struct v4l2_ext_control *) malloc(sizeof(struct v4l2_ext_control));
+
+
+ ext_ctrl.count = 0;
+ ext_ctrl.controls->id = V4L2_CID_RDS_TX_PTY;
+ ext_ctrl.controls->size = 0;
+ ext_ctrl.controls->string = NULL;
+ ext_ctrl.controls->value = *pty_code;
+
+ ret = ioctl(fd, VIDIOC_S_EXT_CTRLS, &amp; ext_ctrl);
+ if (ret &lt; 0) {
+ printf("VIDIOC_S_EXT_CTRLS:error!!\n");
+ }
+ free(ext_ctrl.controls);
+ }
+ void rds_tx_PSN(void *value)
+ {
+ struct v4l2_ext_controls ext_ctrl;
+ int ret;
+ char *psn = (char *)value;
+
+ ext_ctrl.ctrl_class = V4L2_CTRL_CLASS_FM_TX;
+ ext_ctrl.controls = (struct v4l2_ext_control *) malloc(sizeof(struct v4l2_ext_control));
+
+
+ ext_ctrl.count = 0;
+ ext_ctrl.controls->id = V4L2_CID_RDS_TX_PS_NAME;
+ ext_ctrl.controls->size = strlen(psn);
+ ext_ctrl.controls->value = 0;
+ ext_ctrl.controls->string = (char *)malloc(ext_ctrl.controls->size);
+ memcpy(ext_ctrl.controls->string, psn, ext_ctrl.controls->size);
+
+ ret = ioctl(fd, VIDIOC_S_EXT_CTRLS, &amp; ext_ctrl);
+ if (ret &lt; 0) {
+ printf("VIDIOC_S_EXT_CTRLS:error!!\n");
+ }
+ free(ext_ctrl.controls->string);
+ free(ext_ctrl.controls);
+
+ }
+ void rds_tx_RT(void *value)
+ {
+ struct v4l2_ext_controls ext_ctrl;
+ int ret;
+ char *radio_text = (char *)value;
+
+ ext_ctrl.ctrl_class = V4L2_CTRL_CLASS_FM_TX;
+ ext_ctrl.controls = (struct v4l2_ext_control *) malloc(sizeof(struct v4l2_ext_control));
+
+
+ ext_ctrl.count = 0;
+ ext_ctrl.controls->id = V4L2_CID_RDS_TX_RADIO_TEXT;
+ ext_ctrl.controls->size = strlen(radio_text);
+ ext_ctrl.controls->value = 0;
+ ext_ctrl.controls->string = (char *)malloc(ext_ctrl.controls->size);
+ memcpy(ext_ctrl.controls->string, radio_text, ext_ctrl.controls->size);
+
+ ret = ioctl(fd, VIDIOC_S_EXT_CTRLS, &amp; ext_ctrl);
+ if (ret &lt; 0) {
+ printf("VIDIOC_S_EXT_CTRLS:error!!\n");
+ }
+ free(ext_ctrl.controls->string);
+ free(ext_ctrl.controls);
+
+ }
+
+ </programlisting>
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </section>
+ </chapter>
<chapter id="driver-configuration">
<title>Driver Configuration and Interaction</title>
@@ -651,7 +950,7 @@
</varlistentry>
<varlistentry>
<term>Runtime readable/modifiable</term>
- <listitem><para>Modifiable</para></listitem>
+ <listitem><para>Readable</para></listitem>
</varlistentry>
<varlistentry>
<term>Description</term>
@@ -659,9 +958,9 @@
<para>
The parameter grid in radio-CG2900.c defines the spacing to be used in Khz while switching on FM Radio.
<itemizedlist>
- <listitem><para>0: 200 kHz (USA)</para></listitem>
+ <listitem><para>0: 50 kHz (China)</para></listitem>
<listitem><para>1: 100 kHz (Europe, Japan)</para></listitem>
- <listitem><para>2: 50 kHz (China)</para></listitem>
+ <listitem><para>2: 200 kHz (USA)</para></listitem>
</itemizedlist>
</para>
</listitem>
@@ -679,6 +978,12 @@
switching on FM Radio, otherwise the change takes effect
from next FM switch on.
</para>
+ <para>
+ Note: The Grid parameter cannot be changed during FM radio is operational.
+ </para>
+ <para>
+ The user must change the grid value and restart the FM radio when moving into a different radio region.
+ </para>
</listitem>
</varlistentry>
<varlistentry>
@@ -714,7 +1019,7 @@
</varlistentry>
<varlistentry>
<term>Runtime readable/modifiable</term>
- <listitem><para>Modifiable</para></listitem>
+ <listitem><para>Readable</para></listitem>
</varlistentry>
<varlistentry>
<term>Description</term>
@@ -723,8 +1028,8 @@
The parameter band in radio-CG2900.c defines the band to be used while switching on FM Radio.
<itemizedlist>
<listitem><para>0: 87.5 - 108 MHz (USA, Europe)</para></listitem>
- <listitem><para>1: 70 - 108 MHz (China wide band)</para></listitem>
- <listitem><para>2: 76 - 90 MHz (Japan)</para></listitem>
+ <listitem><para>1: 76 - 90 MHz (Japan)</para></listitem>
+ <listitem><para>2: 70 - 108 MHz (China wide band)</para></listitem>
</itemizedlist>
</para>
</listitem>
@@ -741,6 +1046,12 @@
The change is applicable before switching on FM Radio,
otherwise the change takes effect from next FM switch on.
</para>
+ <para>
+ Note: The band parameter cannot be changed during FM radio is operational.
+ </para>
+ <para>
+ The user must change the band value and restart the FM radio when moving into a different radio region.
+ </para>
</listitem>
</varlistentry>
<varlistentry>
@@ -774,7 +1085,7 @@
</varlistentry>
<varlistentry>
<term>Runtime readable/modifiable</term>
- <listitem><para>Modifiable</para></listitem>
+ <listitem><para>Readable</para></listitem>
</varlistentry>
<varlistentry>
<term>Description</term>
@@ -852,7 +1163,7 @@
<term>Description</term>
<listitem>
<para>
- The <constant>VIDIOC_QUERYCAP</constant> IOCTL is used to query the capabilities supported by FM Driver. IF the FM Driver supports FM Rx it should set the capabilities field bit should be ored with V4L2_CAP_TUNER, otherwise if it supports FM Tx, the capabilities field bit should be ored with V4L2_CAP_MODULATOR.
+ The <constant>VIDIOC_QUERYCAP</constant> IOCTL is used to query the capabilities supported by FM Driver. IF the FM Driver supports FM Rx it should set the capabilities field bit should be bitwise OR'd with V4L2_CAP_TUNER, otherwise if it supports FM Tx, the capabilities field bit should be bitwise OR'd with V4L2_CAP_MODULATOR.
Returned values are:
<itemizedlist>
<listitem><para>If IOCTL is able to retrive the Capabilities successfully without errors the IOCTL function will return 0.</para></listitem>
@@ -881,7 +1192,7 @@
<term>Description</term>
<listitem>
<para>
- The <constant>VIDIOC_G_TUNER</constant> IOCTL gets the FM Radio Tuner properties supported.
+ The <constant>VIDIOC_G_TUNER</constant> IOCTL gets the FM Radio Tuner properties supported by FM Radio. It is also used to retrieve RDS status, mono/stereo status and Signal strength of the tuned channel. These values are valid when FM is configured using IOCTL VIDIOC_S_TUNER, i.e in FM Rx mode.
Returned values are:
<itemizedlist>
<listitem><para>If IOCTL is able to retrive the tuner properties successfully without errors the IOCTL function will return 0.</para></listitem>
@@ -923,6 +1234,35 @@
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><constant>VIDIOC_G_MODULATOR</constant></term>
+ <listitem>
+ <variablelist>
+ <varlistentry>
+ <term>Direction</term>
+ <listitem><para>Get</para></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Parameter</term>
+ <listitem><synopsis><type>v4l2_tuner</type></synopsis></listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>Description</term>
+ <listitem>
+ <para>
+ The <constant>VIDIOC_G_MODULATOR</constant> IOCTL gets the FM Radio Modulator properties supported by FM Radio. It is also used to retrieve RDS status and mono/stereo status. These values are valid when FM is configured using IOCTL VIDIOC_S_MODULATOR, i.e in FM Tx mode.
+ Returned values are:
+ <itemizedlist>
+ <listitem><para>If IOCTL is able to retrive the tuner properties successfully without errors the IOCTL function will return 0.</para></listitem>
+ <listitem><para>A negative value will indicate error.</para></listitem>
+ </itemizedlist>
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </listitem>
+ </varlistentry>
+
<varlistentry>
<term><constant>VIDIOC_S_MODULATOR</constant></term>
<listitem>
@@ -1058,30 +1398,33 @@
The <constant>VIDIOC_G_CTRL</constant> IOCTL to retrive value of a paticular control. The following controls are supported by FM Driver:
<itemizedlist>
<listitem><para>
- V4L2_CID_CG2900_RADIO_RSSI_LEVEL
+ V4L2_CID_AUDIO_VOLUME
</para></listitem>
<listitem><para>
- V4L2_CID_CG2900_RADIO_RSSI_THRESHOLD
+ V4L2_CID_AUDIO_MUTE
</para></listitem>
<listitem><para>
- V4L2_CID_CG2900_RADIO_RDS_AF_UPDATE_GET_RESULTS
+ V4L2_CID_AUDIO_BALANCE
</para></listitem>
<listitem><para>
- V4L2_CID_CG2900_RADIO_RDS_AF_SWITCH_GET_RESULTS
+ V4L2_CID_CG2900_RADIO_RSSI_THRESHOLD
</para></listitem>
<listitem><para>
- V4L2_CID_CG2900_RADIO_RSSI_LEVEL
+ V4L2_CID_CG2900_RADIO_SELECT_ANTENNA
</para></listitem>
<listitem><para>
- V4L2_CID_CG2900_RADIO_RSSI_LEVEL
+ V4L2_CID_CG2900_RADIO_RDS_AF_UPDATE_GET_RESULT
+ </para></listitem>
+ <listitem><para>
+ V4L2_CID_CG2900_RADIO_RDS_AF_SWITCH_GET_RESULT
</para></listitem>
</itemizedlist>
- Returned values are:
+ Common Returned values are:
<itemizedlist>
<listitem><para>If IOCTL is able to retrive the value of the control successfully without errors the IOCTL function will return 0.</para></listitem>
<listitem><para>A negative value will indicate error.</para></listitem>
</itemizedlist>
- </para>
+ </para>
</listitem>
</varlistentry>
</variablelist>
@@ -1110,9 +1453,6 @@
V4L2_CID_CG2900_RADIO_CHIP_STATE
</para></listitem>
<listitem><para>
- V4L2_CID_CG2900_RADIO_RDS_STATE
- </para></listitem>
- <listitem><para>
V4L2_CID_CG2900_RADIO_BANDSCAN
</para></listitem>
<listitem><para>
@@ -1313,7 +1653,7 @@
</chapter>
<chapter id="bugs">
- <title>Known Bugs And Assumptions</title>
+ <title>Known Bugs And Limitations</title>
<!-- Do NOT change the chapter id or title! -->
<para>
<variablelist>
@@ -1335,6 +1675,25 @@
</varlistentry>
</variablelist>
+ <variablelist>
+ <varlistentry>
+ <term>Problems in Block Scan to retreive RSSI of channels in FM Band</term>
+ <listitem>
+ <para>
+ The Block Scan retrives many stations which are not actual FM stations, this is currently under investigation.
+ <!-- TODO: Briefly describe the limitation, unless all
+ information is already present in the title.
+ Use full english sentences.
+ Repeat the varlistentry for each limitation.
+ If none are known, replace this varlistentry
+ with the one below. -->
+ <!-- TODO: This guideline for this chapter may be extended
+ during the user-guide guidelines drop. -->
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+
</para>
</chapter>
diff --git a/drivers/media/radio/CG2900/fmdriver.c b/drivers/media/radio/CG2900/fmdriver.c
index 1fc93077fce..1af7b527df0 100755
--- a/drivers/media/radio/CG2900/fmdriver.c
+++ b/drivers/media/radio/CG2900/fmdriver.c
@@ -1,6 +1,4 @@
/*
- * file fmdriver.c
- *
* Copyright (C) ST-Ericsson SA 2010
*
* Linux FM Driver for CG2900 FM Chip
@@ -15,612 +13,636 @@
#include "fmdriver.h"
#include "platformosapi.h"
-/** the count of interrupt sources of the system */
#define MAX_COUNT_OF_IRQS 16
+#define CHANNEL_FREQUENCY_CONVERTER 50
+#define MAX_NAME_SIZE 50
+#define MIN_POWER_LEVEL 88
+#define MAX_POWER_LEVEL 123
+#define DEFAULT_RDS_DEVIATION 200
+#define MAX_RDS_DEVIATION 750
+#define DEFAULT_PILOT_DEVIATION 675
+#define MAX_PILOT_DEVIATION 1000
+#define DEFAULT_RSSI_THRESHOLD 0x0100
#define ASCVAL(x)(((x) <= 9) ? (x) + '0' : (x) - 10 + 'a')
-/** Variable for state of library */
-static bool g_fmd_initalized = STE_FALSE;
-
-/** Variables for synchronization of Interrupts to other function calls */
-static bool g_fmd_interrupt_mutex = STE_FALSE;
-static int g_fmd_interrupt_semaphore;
-/** STE_TRUE if an interrupt needs to be handled */
-static bool g_interrupt_received[MAX_COUNT_OF_IRQS] = {STE_FALSE};
-/** forward declaration of the interrupt handler function */
-static char g_tempstring[50];
-
/**
- * enum fmd_gocmd_e - FM Driver Command state .
- * @fmd_gocmd_none: FM Driver in Idle state
- * @fmd_gocmd_setmode: FM Driver in setmode state
- * @fmd_gocmd_setfrequency: FM Driver in Set frequency state.
- * @fmd_gocmd_setantenna: FM Driver in Setantenna state
- * @fmd_gocmd_setmute: FM Driver in Setmute state
- * @fmd_gocmd_seek: FM Driver in seek mode
- * @fmd_gocmd_seekstop: FM Driver in seek stop level state.
- * @fmd_gocmd_scanband: FM Driver in Scanband mode
- * @fmd_gocmd_stepfrequency: FM Driver in StepFreq state
- * @fmd_gocmd_genpowerup: FM Driver in Power UP state
+ * enum fmd_gocmd_t - FM Driver Command state.
+ * @FMD_STATE_NONE: FM Driver in Idle state
+ * @FMD_STATE_MODE: FM Driver in setmode state
+ * @FMD_STATE_FREQUENCY: FM Driver in Set frequency state.
+ * @FMD_STATE_PA: FM Driver in SetPA state.
+ * @FMD_STATE_PA_LEVEL: FM Driver in Setpalevl state.
+ * @FMD_STATE_ANTENNA: FM Driver in Setantenna state
+ * @FMD_STATE_MUTE: FM Driver in Setmute state
+ * @FMD_STATE_SEEK: FM Driver in seek mode
+ * @FMD_STATE_SEEK_STOP: FM Driver in seek stop level state.
+ * @FMD_STATE_SCAN_BAND: FM Driver in Scanband mode
+ * @FMD_STATE_TX_SET_CTRL: FM Driver in RDS control state
+ * @FMD_STATE_TX_SET_THRSHLD: FM Driver in RDS threshld state
+ * @FMD_STATE_GEN_POWERUP: FM Driver in Power UP state.
+ * @FMD_STATE_SELECT_REF_CLK: FM Driver in Select Reference clock state.
+ * @FMD_STATE_SET_REF_CLK_PLL: FM Driver in Set Reference Freq state.
+ * @FMD_STATE_BLOCK_SCAN: FM Driver in Block Scan state.
+ * @FMD_STATE_AF_UPDATE: FM Driver in AF Update State.
+ * @FMD_STATE_AF_SWITCH: FM Driver in AF Switch State.
+ * @FMD_STATE_MONOSTEREO_TRANSITION:FM Driver in Monostereo transition state.
+ * Various states of the FM driver.
*/
-enum fmd_gocmd_e {
- fmd_gocmd_none,
- fmd_gocmd_setmode,
- fmd_gocmd_setfrequency,
- fmd_gocmd_setantenna,
- fmd_gocmd_setmute,
- fmd_gocmd_seek,
- fmd_gocmd_seekstop,
- fmd_gocmd_scanband,
- fmd_gocmd_stepfrequency,
- fmd_gocmd_genpowerup,
+enum fmd_gocmd_t {
+ FMD_STATE_NONE,
+ FMD_STATE_MODE,
+ FMD_STATE_FREQUENCY,
+ FMD_STATE_PA,
+ FMD_STATE_PA_LEVEL,
+ FMD_STATE_ANTENNA,
+ FMD_STATE_MUTE,
+ FMD_STATE_SEEK,
+ FMD_STATE_SEEK_STOP,
+ FMD_STATE_SCAN_BAND,
+ FMD_STATE_TX_SET_CTRL,
+ FMD_STATE_TX_SET_THRSHLD,
+ FMD_STATE_GEN_POWERUP,
+ FMD_STATE_SELECT_REF_CLK,
+ FMD_STATE_SET_REF_CLK_PLL,
+ FMD_STATE_BLOCK_SCAN,
+ FMD_STATE_AF_UPDATE,
+ FMD_STATE_AF_SWITCH,
+ FMD_STATE_MONOSTEREO_TRANSITION
};
/**
- * struct fmd_rdsgroup_s - Main rds group structure.
+ * struct fmd_rdsgroup_t - Rds group structure.
* @block: Array for RDS Block(s) received.
* @status: Array of Status of corresponding RDS block(s).
+ * It stores the value and status of a particular RDS group
+ * received.
*/
-struct fmd_rdsgroup_s {
- unsigned short block[4];
- unsigned char status[4];
-} ;
+struct fmd_rdsgroup_t {
+ u16 block[NUM_OF_RDS_BLOCKS];
+ u8 status[NUM_OF_RDS_BLOCKS];
+} __attribute__ ((packed));
/**
- * struct struct fmd_state_info_s - Main FM state info structure.
- * @mode: fm mode(idle/RX/TX).
- * @logginglevel: 0 = off, 1 = basic, 2 = all.
- * @rx_grid: Rceiver Grid
+ * struct struct fmd_state_info_t - Main FM state info structure.
+ * @fmd_initalized: Flag indicating FM Driver is initialized or not
* @rx_freqrange: Receiver freq range
- * @rx_stereomode: Rceiver Stereo mode
* @rx_volume: Receiver volume level
- * @rx_balance: Rceiver Balance level
- * @rx_mute: Receiver Mute
* @rx_antenna: Receiver Antenna
- * @rx_deemphasis: Receiver Deemphasis
- * @rx_rdson: Receiver RDS ON
+ * @rdsbufcnt: Number of RDS Groups available
* @rx_seek_stoplevel: RDS seek stop Level
- * @gocmd: pipe line Command
+ * @rx_rdson: Receiver RDS ON
+ * @rx_stereomode: Receiver Stereo mode
+ * @max_channels_to_scan: Maximum Number of channels to Scan.
+ * @tx_freqrange: Transmitter freq Range
+ * @tx_preemphasis: Transmitter Pre emphiasis level
+ * @tx_stereomode: Transmitter stero mode
+ * @tx_rdson: Enable RDS
+ * @tx_pilotdev: PIlot freq deviation
+ * @tx_rdsdev: RDS deviation
+ * @tx_strength: TX Signal Stregnth
+ * @irq_index: Index where last interrupt is added to Interrupt queue
+ * @interrupt_available_for_processing: Flag indicating if interrupt is
+ * available for processing or not.
+ * @interrupt_queue: Circular Queue to store the received interrupt from chip.
+ * @gocmd: Command which is in progress.
* @rdsgroup: Array of RDS group Buffer
- * @rdsbufcnt: Number of RDS Groups available
- * @callback: Callback registered by upper layers.
+ * @callback: Callback registered by upper layers.
*/
-struct fmd_state_info_s {
- uint8_t mode;
- uint8_t logginglevel;
- uint8_t rx_grid;
- uint8_t rx_freqrange;
- uint32_t rx_stereomode;
- uint8_t rx_volume;
- int8_t rx_balance;
- bool rx_mute;
- uint8_t rx_antenna;
- uint8_t rx_deemphasis;
- bool rx_rdson;
- uint16_t rx_seek_stoplevel;
-
- enum fmd_gocmd_e gocmd;
- struct fmd_rdsgroup_s rdsgroup[22];
- uint8_t rdsbufcnt;
- fmd_radio_cb callback;
-} fmd_state_info;
+struct fmd_state_info_t {
+ bool fmd_initalized;
+ u8 rx_freqrange;
+ u8 rx_volume;
+ u8 rx_antenna;
+ u8 rdsbufcnt;
+ u16 rx_seek_stoplevel;
+ bool rx_rdson;
+ u8 rx_stereomode;
+ u8 tx_freqrange;
+ u8 tx_preemphasis;
+ bool tx_stereomode;
+ u8 max_channels_to_scan;
+
+ bool tx_rdson;
+ u16 tx_pilotdev;
+ u16 tx_rdsdev;
+ u16 tx_strength;
+
+ u8 irq_index;
+ bool interrupt_available_for_processing;
+ u16 interrupt_queue[MAX_COUNT_OF_IRQS];
+ enum fmd_gocmd_t gocmd;
+ struct fmd_rdsgroup_t rdsgroup[MAX_RDS_GROUPS];
+ fmd_radio_cb callback;
+} __attribute__ ((packed));
/**
- * struct fmd_data_s - Main structure for FM data exchange.
+ * struct fmd_data_t - Main structure for FM data exchange.
* @cmd_id: Command Id of the command being exchanged.
* @num_parameters: Number of parameters
- * @parameters: Pointer to FM data parameters.
+ * @parameters: FM data parameters.
*/
-struct fmd_data_s {
- uint32_t cmd_id;
- uint16_t num_parameters;
- uint8_t *parameters;
-} fmd_data;
+struct fmd_data_t {
+ u32 cmd_id;
+ u16 num_parameters;
+ u8 *parameters;
+} __attribute__ ((packed));
+
+static struct fmd_state_info_t fmd_state_info;
+static struct fmd_data_t fmd_data;
+
+static char event_name[FMD_EVENT_LAST_ELEMENT][MAX_NAME_SIZE] = {
+ "FMD_EVENT_ANTENNA_STATUS_CHANGED",
+ "FMD_EVENT_FREQUENCY_CHANGED",
+ "FMD_EVENT_SEEK_COMPLETED",
+ "FMD_EVENT_SCAN_BAND_COMPLETED",
+ "FMD_EVENT_BLOCK_SCAN_COMPLETED",
+ "FMD_EVENT_AF_UPDATE_SWITCH_COMPLETE",
+ "FMD_EVENT_MONOSTEREO_TRANSITION_COMPLETE",
+ "FMD_EVENT_SEEK_STOPPED",
+ "FMD_EVENT_GEN_POWERUP",
+ "FMD_EVENT_RDSGROUP_RCVD",
+};
+
+static char interrupt_name[MAX_COUNT_OF_IRQS][MAX_NAME_SIZE] = {
+ "irpt_OperationSucceeded",
+ "irpt_OperationFailed",
+ "-",
+ "irpt_BufferFull/Empty",
+ "irpt_SignalQualityLow/MuteStatusChanged",
+ "irpt_MonoStereoTransition",
+ "irpt_RdsSyncFound/InputOverdrive",
+ "irpt_RdsSyncLost",
+ "irpt_PiCodeChanged",
+ "irpt_RequestedBlockAvailable",
+ "-",
+ "-",
+ "-",
+ "-",
+ "irpt_WarmBootReady",
+ "irpt_ColdBootReady",
+};
/* ------------------ Internal function declarations ---------------------- */
-static void fmd_criticalsection_enter(void);
-static void fmd_criticalsection_leave(void);
-static void fmd_event_name(
- unsigned long event,
- char *str
- );
-static void fmd_interrupt_name(
- unsigned long interrupt,
- char *str
- );
-static void fmd_interrupt_handler(
- const unsigned long interrupt
- );
-static void fmd_handle_interrupt(void);
-static void fmd_handle_synchronized_interrupt(
- unsigned long interrupt
- );
-static void fmd_callback(
- void *context,
- uint32_t event,
- uint32_t event_int_data,
- bool event_boolean_data
- );
-static unsigned short fmd_rx_frequency_to_channel(
- void *context,
- uint32_t freq
- );
-static uint32_t fmd_rx_channel_to_frequency(
- void *context,
- unsigned short chan
- );
+static void fmd_event_name(u8 event, char *event_name);
+static void fmd_interrupt_name(u16 interrupt, char *interrupt_name);
+static void fmd_add_interrupt_to_queue(u16 interrupt);
+static void fmd_process_interrupt(u16 interrupt);
+static void fmd_callback(void *context, u8 event, bool event_successful);
+static u16 fmd_rx_frequency_to_channel(void *context, u32 freq);
+static u32 fmd_rx_channel_to_frequency(void *context, u16 channel_number);
+static u16 fmd_tx_frequency_to_channel(void *context, u32 freq);
+static u32 fmd_tx_channel_to_frequency(void *context, u16 channel_number);
static bool fmd_go_cmd_busy(void);
-static unsigned int fmd_send_cmd_and_read_resp(
- const unsigned long cmd_id,
- const unsigned int num_parameters,
- const unsigned short *parameters,
- unsigned int *resp_num_parameters,
- unsigned short *resp_parameters
- );
-static unsigned int fmd_send_cmd(
- const unsigned long cmd_id ,
- const unsigned int num_parameters,
- const unsigned short *parameters
- );
-static unsigned int fmd_read_resp(
- unsigned long *cmd_id,
- unsigned int *num_parameters,
- unsigned short *parameters
- );
-static void fmd_process_fm_function(
- uint8_t *packet_buffer
- );
-static unsigned int fmd_st_write_file_block(
- uint32_t file_block_id,
- uint8_t *file_block,
- uint16_t file_block_length
- );
+static u8 fmd_send_cmd_and_read_resp(const u16 cmd_id,
+ const u16 num_parameters,
+ const u16 *parameters,
+ u16 *resp_num_parameters,
+ u16 *resp_parameters);
+static u8 fmd_send_cmd(const u16 cmd_id,
+ const u16 num_parameters, const u16 *parameters);
+static u8 fmd_read_resp(u16 *cmd_id, u16 *num_parameters, u16 *parameters);
+static void fmd_process_fm_function(u8 *packet_buffer);
+static u8 fmd_write_file_block(u32 file_block_id,
+ u8 *file_block, u16 file_block_length);
/* ------------------ Internal function definitions ---------------------- */
/**
- * fmd_criticalsection_enter() - Critical Section for FM Driver.
- * This is used for interrupt syncronisation.
- */
-static void fmd_criticalsection_enter(void)
-{
- g_fmd_interrupt_semaphore++;
- g_fmd_interrupt_mutex = STE_TRUE;
-}
-
-/**
- * fmd_criticalsection_leave() - Critical Section for FM Driver.
- * This is used for interrupt syncronisation.
+ * fmd_event_name() - Converts the event to a displayable string.
+ * @event: Event that has occurred.
+ * @eventname: (out) Buffer to store event name.
*/
-static void fmd_criticalsection_leave(void)
+static void fmd_event_name(u8 event, char *eventname)
{
- g_fmd_interrupt_semaphore--;
- if (g_fmd_interrupt_semaphore == 0)
- g_fmd_interrupt_mutex = STE_FALSE;
- fmd_handle_interrupt(); /* execute buffered interrupts */
-}
-
-/**
- * fmd_event_name() - Converts the event to a Displayable String
- * @event: event that has occurred.
- * @str: (out) Pointer to the buffer to store event Name.
- */
-static void fmd_event_name(
- unsigned long event,
- char *str
- )
-{
- switch (event) {
- case FMD_EVENT_ANTENNA_STATUS_CHANGED:
- strcpy(str, "FMD_EVENT_ANTENNA_STATUS_CHANGED");
- break;
- case FMD_EVENT_FREQUENCY_CHANGED:
- strcpy(str, "FMD_EVENT_FREQUENCY_CHANGED");
- break;
- case FMD_EVENT_FREQUENCY_RANGE_CHANGED:
- strcpy(str, "FMD_EVENT_FREQUENCY_RANGE_CHANGED");
- break;
- case FMD_EVENT_PRESET_CHANGED:
- strcpy(str, "FMD_EVENT_PRESET_CHANGED");
- break;
- case FMD_EVENT_SEEK_COMPLETED:
- strcpy(str, "FMD_EVENT_SEEK_COMPLETED");
- break;
- case FMD_EVENT_ACTION_FINISHED:
- strcpy(str, "FMD_EVENT_ACTION_FINISHED");
- break;
- case FMD_EVENT_RDSGROUP_RCVD:
- strcpy(str, "FMD_EVENT_RDSGROUP_RCVD");
- break;
- case FMD_EVENT_SEEK_STOPPED:
- strcpy(str, "FMD_EVENT_SEEK_STOPPED");
- break;
- default:
- strcpy(str, "Unknown Event");
- break;
+ if (eventname != NULL) {
+ if (event < FMD_EVENT_LAST_ELEMENT)
+ strcpy(eventname, event_name[event]);
+ else
+ strcpy(eventname, "FMD_EVENT_UNKNOWN");
+ } else {
+ FM_ERR_REPORT("fmd_event_name: Output Buffer is NULL!!!");
}
}
/**
- * fmd_interrupt_name() - Converts the interrupt to a Displayable String
+ * fmd_interrupt_name() - Converts the interrupt to a displayable string.
* @interrupt: interrupt received from FM Chip
- * @str: (out) Pointer to the buffer to store interrupt Name.
+ * @interruptname: (out) Buffer to store interrupt name.
*/
-static void fmd_interrupt_name(
- unsigned long interrupt,
- char *str
- )
-{
- switch (interrupt) {
- case 0:
- strcpy(str, "irpt_OperationSucceeded");
- break;
- case 1:
- strcpy(str, "irpt_OperationFailed");
- break;
- case 2:
- case 10:
- case 11:
- case 12:
- case 13:
- strcpy(str, "-");
- break;
- case 3:
- strcpy(str, "irpt_BufferFull/Empty");
- break;
- case 4:
- strcpy(str, "irpt_SignalQualityLow/MuteStatusChanged");
- break;
- case 5:
- strcpy(str, "irpt_MonoStereoTransition");
- break;
- case 6:
- strcpy(str, "irpt_RdsSyncFound/InputOverdrive");
- break;
- case 7:
- strcpy(str, "irpt_RdsSyncLost");
- break;
- case 8:
- strcpy(str, "irpt_PiCodeChanged");
- break;
- case 9:
- strcpy(str, "irpt_RequestedBlockAvailable");
- break;
- case 14:
- strcpy(str, "irpt_WarmBootReady");
- break;
- case 15:
- strcpy(str, "irpt_ColdBootReady");
- break;
- default:
- strcpy(str, "IRPT Unknown");
- break;
+static void fmd_interrupt_name(u16 interrupt, char *interruptname)
+{
+ int index;
+
+ if (interruptname != NULL) {
+ /* Convert Interrupt to Bit */
+ for (index = 0; index < MAX_COUNT_OF_IRQS; index++) {
+ if (interrupt & (1 << index)) {
+ /* Match found, break the loop */
+ break;
+ }
+ }
+ if (index < MAX_COUNT_OF_IRQS)
+ strcpy(interruptname, interrupt_name[index]);
+ else
+ strcpy(interruptname, "irpt_Unknown");
+ } else {
+ FM_ERR_REPORT("fmd_interrupt_name: Output Buffer is NULL!!!");
}
}
/**
- * fmd_interrupt_handler() - The function is implemented to get the
- * interrupt indication from device.
+ * fmd_add_interrupt_to_queue() - Add interrupt to IRQ Queue.
* @interrupt: interrupt received from FM Chip
*/
-static void fmd_interrupt_handler(
- const unsigned long interrupt
- )
+static void fmd_add_interrupt_to_queue(u16 interrupt)
{
- int i;
- for (i = 0; i < MAX_COUNT_OF_IRQS; i++) {
- if (interrupt & (1 << i)) {
- g_interrupt_received[i] = STE_TRUE;
- fmd_handle_interrupt();
- }
+ FM_DEBUG_REPORT("fmd_add_interrupt_to_queue : "
+ "Interrupt Received = %04x", (u16) interrupt);
+
+ /* Reset the index if it reaches the array limit */
+ if (fmd_state_info.irq_index > MAX_COUNT_OF_IRQS - 1) {
+ os_lock();
+ fmd_state_info.irq_index = 0;
+ os_unlock();
}
-}
-/**
- * fmd_handle_interrupt() - This function synchronizes Interupts in that
- * way that it is only executed when no criticalsection is active.
- * This is also the function that executes the interrupt handlers
- */
-static void fmd_handle_interrupt(void)
-{
- int i;
- if (!g_fmd_interrupt_mutex) {
- /* only execute when there is no other function executed */
-
- /* check if an interrupt was requested */
- for (i = 0; i < MAX_COUNT_OF_IRQS; i++) {
- if (g_interrupt_received[i]) {
- /*handle interrupt(now the irq is
- * synchronized!)
- */
- fmd_handle_synchronized_interrupt(i);
- }
- }
+ os_lock();
+ fmd_state_info.interrupt_queue[fmd_state_info.irq_index] = interrupt;
+ fmd_state_info.irq_index++;
+ os_unlock();
+ if (STE_FALSE == fmd_state_info.interrupt_available_for_processing) {
+ os_lock();
+ fmd_state_info.interrupt_available_for_processing = STE_TRUE;
+ os_unlock();
+ os_set_interrupt_sem();
}
}
/**
- * fmd_handle_synchronized_interrupt() - This function processes the
- * interrupt received from FM Chip and calls the corresponding callback
- * register by upper layers with proper parameters.
+ * fmd_process_interrupt() - Processes the Interrupt.
+ * This function processes the interrupt received from FM Chip
+ * and calls the corresponding callback registered by upper layers with
+ * proper parameters.
* @interrupt: interrupt received from FM Chip
*/
-static void fmd_handle_synchronized_interrupt(
- unsigned long interrupt
- )
+static void fmd_process_interrupt(u16 interrupt)
{
- char irpt_name[50];
-
- fmd_criticalsection_enter();
+ char irpt_name[MAX_NAME_SIZE];
fmd_interrupt_name(interrupt, irpt_name);
FM_DEBUG_REPORT("%s", irpt_name);
- switch (interrupt) {
- case IRPT_OPERATIONSUCCEEDED:
- {
+ if (interrupt & IRPT_OPERATIONSUCCEEDED) {
switch (fmd_state_info.gocmd) {
- case fmd_gocmd_setantenna:
- /* Signal host */
- fmd_state_info.gocmd = fmd_gocmd_none;
- fmd_callback((void *)&fmd_state_info,
- FMD_EVENT_ACTION_FINISHED , 0,
- STE_TRUE);
- fmd_callback((void *)&fmd_state_info,
- FMD_EVENT_ANTENNA_STATUS_CHANGED ,
- 0, STE_FALSE);
- break;
- case fmd_gocmd_setmode:
+ case FMD_STATE_ANTENNA:
/* Signal host */
- fmd_state_info.gocmd = fmd_gocmd_none;
+ fmd_state_info.gocmd &= ~FMD_STATE_ANTENNA;
+ os_set_cmd_sem();
fmd_callback((void *)&fmd_state_info,
- FMD_EVENT_ACTION_FINISHED , 0,
- STE_TRUE);
+ FMD_EVENT_ANTENNA_STATUS_CHANGED,
+ STE_TRUE);
break;
- case fmd_gocmd_setmute:
+ case FMD_STATE_MODE:
/* Signal host */
- fmd_state_info.gocmd = fmd_gocmd_none;
- fmd_callback((void *)&fmd_state_info,
- FMD_EVENT_ACTION_FINISHED , 0,
- STE_TRUE);
+ fmd_state_info.gocmd &= ~FMD_STATE_MODE;
+ os_set_cmd_sem();
break;
- case fmd_gocmd_setfrequency:
+ case FMD_STATE_MUTE:
/* Signal host */
- fmd_state_info.gocmd = fmd_gocmd_none;
- fmd_callback((void *)&fmd_state_info,
- FMD_EVENT_ACTION_FINISHED , 0,
- STE_TRUE);
- fmd_callback((void *)&fmd_state_info,
- FMD_EVENT_FREQUENCY_CHANGED , 0,
- STE_FALSE);
+ fmd_state_info.gocmd &= ~FMD_STATE_MUTE;
+ os_set_cmd_sem();
break;
-
- case fmd_gocmd_seek:
+ case FMD_STATE_FREQUENCY:
/* Signal host */
- fmd_state_info.gocmd = fmd_gocmd_none;
- fmd_callback((void *)&fmd_state_info,
- FMD_EVENT_ACTION_FINISHED , 0,
- STE_TRUE);
+ fmd_state_info.gocmd &= ~FMD_STATE_FREQUENCY;
+ os_set_cmd_sem();
fmd_callback((void *)&fmd_state_info,
- FMD_EVENT_SEEK_COMPLETED , 0,
- STE_FALSE);
+ FMD_EVENT_FREQUENCY_CHANGED, STE_TRUE);
break;
-
- case fmd_gocmd_scanband:
+ case FMD_STATE_SEEK:
/* Signal host */
- fmd_state_info.gocmd = fmd_gocmd_none;
+ fmd_state_info.gocmd &= ~FMD_STATE_SEEK;
fmd_callback((void *)&fmd_state_info,
- FMD_EVENT_ACTION_FINISHED , 0,
- STE_TRUE);
- fmd_callback((void *)&fmd_state_info,
- FMD_EVENT_SCAN_BAND_COMPLETED , 0,
- STE_FALSE);
+ FMD_EVENT_SEEK_COMPLETED, STE_TRUE);
break;
-
- case fmd_gocmd_stepfrequency:
+ case FMD_STATE_SCAN_BAND:
/* Signal host */
- fmd_state_info.gocmd = fmd_gocmd_none;
+ fmd_state_info.gocmd &= ~FMD_STATE_SCAN_BAND;
fmd_callback((void *)&fmd_state_info,
- FMD_EVENT_ACTION_FINISHED , 0,
- STE_TRUE);
+ FMD_EVENT_SCAN_BAND_COMPLETED, STE_TRUE);
+ break;
+ case FMD_STATE_SEEK_STOP:
+ /* Signal host */
+ fmd_state_info.gocmd &= ~FMD_STATE_SEEK_STOP;
+ os_set_cmd_sem();
fmd_callback((void *)&fmd_state_info,
- FMD_EVENT_FREQUENCY_CHANGED , 0,
- STE_FALSE);
+ FMD_EVENT_SEEK_STOPPED, STE_TRUE);
+ break;
+ case FMD_STATE_PA:
+ /* Signal host */
+ fmd_state_info.gocmd &= ~FMD_STATE_PA;
+ os_set_cmd_sem();
+ break;
+ case FMD_STATE_PA_LEVEL:
+ /* Signal host */
+ fmd_state_info.gocmd &= ~FMD_STATE_PA_LEVEL;
+ os_set_cmd_sem();
break;
- case fmd_gocmd_seekstop:
+ case FMD_STATE_GEN_POWERUP:
+ /* Signal host */
+ fmd_state_info.gocmd &= ~FMD_STATE_GEN_POWERUP;
+ os_set_cmd_sem();
+ break;
+ case FMD_STATE_SELECT_REF_CLK:
+ /* Signal host */
+ fmd_state_info.gocmd &= ~FMD_STATE_SELECT_REF_CLK;
+ os_set_cmd_sem();
+ break;
+ case FMD_STATE_SET_REF_CLK_PLL:
+ /* Signal host */
+ fmd_state_info.gocmd &= ~FMD_STATE_SET_REF_CLK_PLL;
+ os_set_cmd_sem();
+ break;
+ case FMD_STATE_BLOCK_SCAN:
/* Signal host */
- fmd_state_info.gocmd = fmd_gocmd_none;
+ fmd_state_info.gocmd &= ~FMD_STATE_BLOCK_SCAN;
fmd_callback((void *)&fmd_state_info,
- FMD_EVENT_ACTION_FINISHED , 0,
- STE_TRUE);
+ FMD_EVENT_BLOCK_SCAN_COMPLETED, STE_TRUE);
+ break;
+ case FMD_STATE_AF_UPDATE:
+ /* Signal host */
+ fmd_state_info.gocmd &= ~FMD_STATE_AF_UPDATE;
+ os_set_cmd_sem();
fmd_callback((void *)&fmd_state_info,
- FMD_EVENT_SEEK_STOPPED , 0,
- STE_FALSE);
+ FMD_EVENT_AF_UPDATE_SWITCH_COMPLETE,
+ STE_TRUE);
break;
-
- case fmd_gocmd_genpowerup:
+ case FMD_STATE_AF_SWITCH:
/* Signal host */
- fmd_state_info.gocmd = fmd_gocmd_none;
+ fmd_state_info.gocmd &= ~FMD_STATE_AF_SWITCH;
+ os_set_cmd_sem();
fmd_callback((void *)&fmd_state_info,
- FMD_EVENT_ACTION_FINISHED , 0,
- STE_TRUE);
+ FMD_EVENT_AF_UPDATE_SWITCH_COMPLETE,
+ STE_TRUE);
+ break;
+ case FMD_STATE_TX_SET_CTRL:
+ /* Signal host */
+ fmd_state_info.gocmd &= ~FMD_STATE_TX_SET_CTRL;
+ os_set_cmd_sem();
+ break;
+ case FMD_STATE_TX_SET_THRSHLD:
+ /* Signal host */
+ fmd_state_info.gocmd &= ~FMD_STATE_TX_SET_THRSHLD;
+ os_set_cmd_sem();
break;
-
default:
/* Clear the variable */
- fmd_state_info.gocmd = fmd_gocmd_none;
+ fmd_state_info.gocmd = FMD_STATE_NONE;
break;
}
- break;
}
- case IRPT_OPERATIONFAILED:
- {
+ if (interrupt & IRPT_OPERATIONFAILED) {
switch (fmd_state_info.gocmd) {
- case fmd_gocmd_seek:
+ case FMD_STATE_SEEK:
/* Signal host */
- fmd_state_info.gocmd = fmd_gocmd_none;
- fmd_callback((void *)&fmd_state_info,
- FMD_EVENT_ACTION_FINISHED , 0,
- STE_FALSE);
+ fmd_state_info.gocmd = FMD_STATE_NONE;
fmd_callback((void *)&fmd_state_info,
- FMD_EVENT_SEEK_COMPLETED , 0,
- STE_FALSE);
+ FMD_EVENT_SEEK_COMPLETED, STE_FALSE);
break;
- case fmd_gocmd_scanband:
+ case FMD_STATE_SCAN_BAND:
/* Signal host */
- fmd_state_info.gocmd = fmd_gocmd_none;
+ fmd_state_info.gocmd = FMD_STATE_NONE;
fmd_callback((void *)&fmd_state_info,
- FMD_EVENT_ACTION_FINISHED , 0,
- STE_FALSE);
+ FMD_EVENT_SCAN_BAND_COMPLETED, STE_FALSE);
+ break;
+
+ case FMD_STATE_SEEK_STOP:
+ /* Signal host */
+ fmd_state_info.gocmd = FMD_STATE_NONE;
+ os_set_cmd_sem();
fmd_callback((void *)&fmd_state_info,
- FMD_EVENT_SCAN_BAND_COMPLETED , 0,
- STE_FALSE);
+ FMD_EVENT_SEEK_STOPPED, STE_FALSE);
break;
- case fmd_gocmd_seekstop:
+ case FMD_STATE_BLOCK_SCAN:
/* Signal host */
- fmd_state_info.gocmd = fmd_gocmd_none;
+ fmd_state_info.gocmd = FMD_STATE_NONE;
fmd_callback((void *)&fmd_state_info,
- FMD_EVENT_ACTION_FINISHED , 0,
- STE_FALSE);
+ FMD_EVENT_BLOCK_SCAN_COMPLETED, STE_FALSE);
+ break;
+
+ case FMD_STATE_AF_UPDATE:
+ case FMD_STATE_AF_SWITCH:
+ /* Signal host */
+ fmd_state_info.gocmd = FMD_STATE_NONE;
+ os_set_cmd_sem();
fmd_callback((void *)&fmd_state_info,
- FMD_EVENT_SEEK_STOPPED , 0,
- STE_FALSE);
+ FMD_EVENT_AF_UPDATE_SWITCH_COMPLETE,
+ STE_FALSE);
break;
default:
/* Clear */
- fmd_state_info.gocmd = fmd_gocmd_none;
+ fmd_state_info.gocmd = FMD_STATE_NONE;
break;
}
- break;
}
- case IRPT_BUFFERFULL:
- {
- switch (fmd_state_info.mode) {
- case FMD_MODE_RX:
+ if (interrupt & IRPT_RX_BUFFERFULL_TX_BUFFEREMPTY) {
+ fmd_callback((void *)&fmd_state_info,
+ FMD_EVENT_RDSGROUP_RCVD, STE_TRUE);
+ }
+
+ if (interrupt & IRPT_RX_MONOSTEREO_TRANSITION) {
+ switch (fmd_state_info.gocmd) {
+ case FMD_STATE_MONOSTEREO_TRANSITION:
+ /* Signal host */
+ fmd_state_info.gocmd &=
+ ~FMD_STATE_MONOSTEREO_TRANSITION;
+ os_set_cmd_sem();
fmd_callback((void *)&fmd_state_info,
- FMD_EVENT_RDSGROUP_RCVD , 0,
- STE_FALSE);;
+ FMD_EVENT_MONOSTEREO_TRANSITION_COMPLETE,
+ STE_TRUE);
break;
+ default:
+ break;
+ }
+ }
+ if (interrupt & IRPT_COLDBOOTREADY) {
+ switch (fmd_state_info.gocmd) {
+ case FMD_STATE_GEN_POWERUP:
+ /* Signal host */
+ fmd_callback((void *)&fmd_state_info,
+ FMD_EVENT_GEN_POWERUP, STE_TRUE);
+ break;
default:
- /* Do Nothing */
- break;
+ /* Do Nothing */
+ break;
}
- break;
}
- case IRPT_COLDBOOTREADY:
- case IRPT_WARMBOOTREADY:
- {
+ if (interrupt & IRPT_WARMBOOTREADY) {
switch (fmd_state_info.gocmd) {
- case fmd_gocmd_genpowerup:
+ case FMD_STATE_GEN_POWERUP:
/* Signal host */
+ fmd_state_info.gocmd &= ~FMD_STATE_GEN_POWERUP;
+ os_set_cmd_sem();
fmd_callback((void *)&fmd_state_info,
- FMD_EVENT_GEN_POWERUP ,
- 0, STE_TRUE);
+ FMD_EVENT_GEN_POWERUP, STE_TRUE);
break;
default:
/* Do Nothing */
break;
}
- break;
}
- }
- g_interrupt_received[interrupt] = STE_FALSE;
- fmd_criticalsection_leave();
}
/**
* fmd_callback() - Callback function for upper layers.
* Callback function that calls the registered callback of upper
* layers with proper parameters.
- * @context: Pointer to the Context of the FM Driver
- * @event: event for which the callback function was caled
+ * @context: Context of the FM Driver
+ * @event: event for which the callback function was called
* from FM Driver.
- * @event_int_data: Data corresponding the event (if any),
- * otherwise it is 0.
- * @event_boolean_data: Signifying whether the event is called from FM Driver
- * on receiving irpt_OperationSucceeded or irpt_OperationFailed.
+ * @event_successful: Signifying whether the event is called from FM
+ * Driver on receiving irpt_OperationSucceeded or irpt_OperationFailed.
*/
-static void fmd_callback(
- void *context,
- uint32_t event,
- uint32_t event_int_data,
- bool event_boolean_data
- )
-{
- fmd_event_name(event, g_tempstring);
- FM_DEBUG_REPORT("%s %x, %x %d", g_tempstring,
- (unsigned int)event , (unsigned int)event_int_data,
- (unsigned int)event_boolean_data);
+static void fmd_callback(void *context, u8 event, bool event_successful)
+{
+ char event_name_string[40];
+ fmd_event_name(event, event_name_string);
+ FM_DEBUG_REPORT("%s %x, %d", event_name_string,
+ (unsigned int)event, (unsigned int)event_successful);
if (fmd_state_info.callback)
fmd_state_info.callback((void *)&context,
- event,
- event_int_data,
- event_boolean_data);
+ event, event_successful);
}
/**
* fmd_rx_frequency_to_channel() - Converts frequency to channel number.
- * Converts the Frequency in Khz to corresponding
- * Channel number. This is used for FM Rx
- * @context: Pointer to the Context of the FM Driver
- * @freq: Frequency in Khz
+ * Converts the Frequency in kHz to corresponding Channel number.
+ * This is used for FM Rx.
+ * @context: Context of the FM Driver.
+ * @freq: Frequency in kHz.
*
* Returns:
* Channel Number corresponding to the given Frequency.
*/
-static unsigned short fmd_rx_frequency_to_channel(
- void *context,
- uint32_t freq
- )
+static u16 fmd_rx_frequency_to_channel(void *context, u32 freq)
{
- uint8_t range;
- uint32_t minfreq, maxfreq, freq_interval;
+ u8 range;
+ u32 minfreq;
+ u32 maxfreq;
fmd_get_freq_range(context, &range);
- fmd_get_freq_range_properties(context, range, &minfreq,
- &maxfreq, &freq_interval);
+ fmd_get_freq_range_properties(context, range, &minfreq, &maxfreq);
if (freq > maxfreq)
freq = maxfreq;
else if (freq < minfreq)
freq = minfreq;
- return (unsigned short)((freq - minfreq) / 50);
+
+ /* Frequency in kHz needs to be divided with 50 kHz to get
+ * channel number for all FM Bands */
+
+ return (u16) ((freq - minfreq) / CHANNEL_FREQUENCY_CONVERTER);
}
/**
* fmd_rx_channel_to_frequency() - Converts Channel number to frequency.
- * Converts the Channel Number to corresponding
- * Frequency in Khz. This is used for FM Rx
- * @context: Pointer to the Context of the FM Driver
- * @chan: Channel Number to be converted
+ * Converts the Channel Number to corresponding Frequency in kHz.
+ * This is used for FM Rx.
+ * @context: Context of the FM Driver.
+ * @channel_number: Channel Number to be converted.
*
* Returns:
- * Frequency corresponding to the corresponding channel.
+ * Frequency corresponding to the corresponding channel in kHz.
*/
-static uint32_t fmd_rx_channel_to_frequency(
- void *context,
- unsigned short chan
- )
+static u32 fmd_rx_channel_to_frequency(void *context, u16 channel_number)
{
- uint8_t range;
- uint32_t freq, minfreq, maxfreq, freq_interval;
+ u8 range;
+ u32 freq;
+ u32 minfreq;
+ u32 maxfreq;
fmd_get_freq_range(context, &range);
- fmd_get_freq_range_properties(context, range, &minfreq,
- &maxfreq, &freq_interval);
- freq = minfreq + (chan*50);
+ fmd_get_freq_range_properties(context, range, &minfreq, &maxfreq);
+
+ /* Channel Number needs to be multiplied with 50 kHz to get
+ * frequency in kHz for all FM Bands */
+
+ freq = minfreq + (channel_number * CHANNEL_FREQUENCY_CONVERTER);
+
+ if (freq > maxfreq)
+ freq = maxfreq;
+ else if (freq < minfreq)
+ freq = minfreq;
+
+ return freq;
+}
+
+/**
+ * fmd_tx_frequency_to_channel() - Converts frequency to channel number.
+ * Converts the Frequency in kHz to corresponding Channel number.
+ * This is used for FM Tx.
+ * @context: Context of the FM Driver.
+ * @freq: Frequency in kHz.
+ *
+ * Returns:
+ * Channel Number corresponding to the given Frequency.
+ */
+static u16 fmd_tx_frequency_to_channel(void *context, u32 freq)
+{
+ u8 range;
+ u32 minfreq;
+ u32 maxfreq;
+
+ fmd_tx_get_freq_range(context, &range);
+ fmd_get_freq_range_properties(context, range, &minfreq, &maxfreq);
+
+ if (freq > maxfreq)
+ freq = maxfreq;
+ else if (freq < minfreq)
+ freq = minfreq;
+
+ /* Frequency in kHz needs to be divided with 50 kHz to get
+ * channel number for all FM Bands */
+
+ return (u16) ((freq - minfreq) / CHANNEL_FREQUENCY_CONVERTER);
+}
+
+/**
+ * fmd_tx_channel_to_frequency() - Converts Channel number to frequency.
+ * Converts the Channel Number to corresponding Frequency in kHz.
+ * This is used for FM Tx.
+ * @context: Context of the FM Driver.
+ * @channel_number: Channel Number to be converted.
+ *
+ * Returns:
+ * Frequency corresponding to the corresponding channel in kHz.
+ */
+static u32 fmd_tx_channel_to_frequency(void *context, u16 channel_number)
+{
+ u8 range;
+ u32 freq;
+ u32 minfreq;
+ u32 maxfreq;
+
+ fmd_tx_get_freq_range(context, &range);
+ fmd_get_freq_range_properties(context, range, &minfreq, &maxfreq);
+
+ /* Channel Number needs to be multiplied with 50 kHz to get
+ * frequency in kHz for all FM Bands */
+
+ freq = minfreq + (channel_number * CHANNEL_FREQUENCY_CONVERTER);
if (freq > maxfreq)
freq = maxfreq;
@@ -635,42 +657,41 @@ static uint32_t fmd_rx_channel_to_frequency(
*
* Returns:
* 0 if FM Driver is Idle
- * 1 otherwise
+ * 1 otherwise
*/
static bool fmd_go_cmd_busy(void)
{
- return (fmd_state_info.gocmd != fmd_gocmd_none);
+ return (fmd_state_info.gocmd != FMD_STATE_NONE);
}
/**
- * fmd_send_cmd_and_read_resp() - This function sends the HCI Command
- * to Protocol Driver and Reads back the Response Packet.
+ * fmd_send_cmd_and_read_resp() - Send command and read response.
+ * This function sends the HCI Command to Protocol Driver and
+ * Reads back the Response Packet.
* @cmd_id: Command Id to be sent to FM Chip.
* @num_parameters: Number of parameters of the command sent.
- * @parameters: Pointer to buffer containing the Buffer to be sent.
+ * @parameters: Buffer containing the Buffer to be sent.
* @resp_num_parameters: (out) Number of paramters of the response packet.
- * @resp_parameters: (out) Pointer to the buffer of the response packet.
+ * @resp_parameters: (out) Buffer of the response packet.
*
* Returns:
- * FMD_RESULT_SUCCESS: If the command is sent successfully and the response
- * receioved is also correct.
+ * FMD_RESULT_SUCCESS: If the command is sent successfully and the
+ * response received is also correct.
* FMD_RESULT_RESPONSE_WRONG: If the received response is not correct.
*/
-static unsigned int fmd_send_cmd_and_read_resp(
- const unsigned long cmd_id,
- const unsigned int num_parameters,
- const unsigned short *parameters,
- unsigned int *resp_num_parameters,
- unsigned short *resp_parameters
- )
+static u8 fmd_send_cmd_and_read_resp(const u16 cmd_id,
+ const u16 num_parameters,
+ const u16 *parameters,
+ u16 *resp_num_parameters,
+ u16 *resp_parameters)
{
- unsigned int result;
- unsigned long readCmdID;
+ u8 result;
+ u16 readCmdID;
result = fmd_send_cmd(cmd_id, num_parameters, parameters);
if (result == FMD_RESULT_SUCCESS) {
result = fmd_read_resp(&readCmdID, resp_num_parameters,
- resp_parameters);
+ resp_parameters);
if (result == FMD_RESULT_SUCCESS) {
/* Check that the response belongs to the sent
* command */
@@ -678,8 +699,7 @@ static unsigned int fmd_send_cmd_and_read_resp(
result = FMD_RESULT_RESPONSE_WRONG;
}
}
- FM_DEBUG_REPORT("fmd_send_cmd_and_read_resp: "\
- "returning %d", result);
+ FM_DEBUG_REPORT("fmd_send_cmd_and_read_resp: " "returning %d", result);
return result;
}
@@ -688,44 +708,46 @@ static unsigned int fmd_send_cmd_and_read_resp(
* to Protocol Driver.
* @cmd_id: Command Id to be sent to FM Chip.
* @num_parameters: Number of parameters of the command sent.
- * @parameters: Pointer to buffer containing the Buffer to be sent.
+ * @parameters: Buffer containing the Buffer to be sent.
*
* Returns:
* 0: If the command is sent successfully to Lower Layers.
* 1: Otherwise
*/
-static unsigned int fmd_send_cmd(
- const unsigned long cmd_id ,
- const unsigned int num_parameters,
- const unsigned short *parameters
- )
-{
- uint32_t TotalLength = 2 + num_parameters * 2 + 5;
- uint8_t *FMData = (uint8_t *)os_mem_alloc(TotalLength);
- uint32_t CmdIDtemp;
- unsigned int err = 0;
-
- /* Wait till response of the last command is received */
- os_get_hal_sem();
-
- /* HCI encapsulation */
- FMData[0] = HCI_PACKET_INDICATOR_FM_CMD_EVT;
- FMData[1] = TotalLength - 2 ;
- FMData[2] = CATENA_OPCODE;
- FMData[3] = FM_WRITE ;
- FMData[4] = FM_FUNCTION_WRITECOMMAND;
-
- CmdIDtemp = cmd_id << 3;
- FMData[5] = (uint8_t)CmdIDtemp;
- FMData[6] = CmdIDtemp >> 8 ;
- FMData[5] |= num_parameters;
-
- os_mem_copy((FMData + 7), (void *)parameters, num_parameters * 2);
-
- /* Send the Packet */
- err = ste_fm_send_packet(TotalLength , FMData);
-
- os_mem_free(FMData);
+static u8 fmd_send_cmd(const u16 cmd_id,
+ const u16 num_parameters, const u16 *parameters)
+{
+ /* Total Length includes 5 bytes HCI Header, 2 bytes to store
+ * number of parameters and remaining bytes depending on
+ * number of paramters */
+ u16 total_length = 2 + num_parameters * sizeof(u16) + 5;
+ u8 *fm_data = (u8 *) os_mem_alloc(total_length);
+ u16 cmd_id_temp;
+ u8 err = 1;
+
+ if (fm_data != NULL) {
+ /* Wait till response of the last command is received */
+ os_get_hal_sem();
+ /* HCI encapsulation */
+ fm_data[0] = HCI_PACKET_INDICATOR_FM_CMD_EVT;
+ fm_data[1] = total_length - 2;
+ fm_data[2] = CATENA_OPCODE;
+ fm_data[3] = FM_WRITE;
+ fm_data[4] = FM_FUNCTION_WRITECOMMAND;
+
+ cmd_id_temp = cmd_id << 3;
+ fm_data[5] = (u8) cmd_id_temp;
+ fm_data[6] = cmd_id_temp >> 8;
+ fm_data[5] |= num_parameters;
+
+ os_mem_copy((fm_data + 7),
+ (void *)parameters, num_parameters * sizeof(u16));
+
+ /* Send the Packet */
+ err = ste_fm_send_packet(total_length, fm_data);
+
+ os_mem_free(fm_data);
+ }
return err;
}
@@ -733,19 +755,15 @@ static unsigned int fmd_send_cmd(
/**
* fmd_read_resp() - This function reads the response packet of the previous
* command sent to FM Chip and copies it to the buffer provided as parameter.
- * @cmd_id: (out) Pointer to Command Id received from FM Chip.
+ * @cmd_id: (out) Command Id received from FM Chip.
* @num_parameters: (out) Number of paramters of the response packet.
- * @parameters: (out) Pointer to the buffer of the response packet.
+ * @parameters: (out) Buffer of the response packet.
*
* Returns:
* 0: If the response buffer is copied successfully.
* 1: Otherwise
*/
-static unsigned int fmd_read_resp(
- unsigned long *cmd_id,
- unsigned int *num_parameters,
- unsigned short *parameters
- )
+static u8 fmd_read_resp(u16 *cmd_id, u16 *num_parameters, u16 *parameters)
{
/* Wait till response of the last command is received */
os_get_read_response_sem();
@@ -755,10 +773,10 @@ static unsigned int fmd_read_resp(
*num_parameters = fmd_data.num_parameters;
if (*num_parameters)
os_mem_copy(parameters, fmd_data.parameters,
- (fmd_data.num_parameters * 2));
+ (fmd_data.num_parameters * 2));
/* Response received, release semaphore so that a new command
- * could be sent to chip */
+ * could be sent to chip */
os_set_hal_sem();
return 0;
@@ -769,51 +787,49 @@ static unsigned int fmd_read_resp(
* This function processes the Response buffer received
* from lower layers for the FM function and performs the necessary action to
* parse the same.
- * @packet_buffer: Pointer to the received Buffer.
+ * @packet_buffer: Received Buffer.
*/
-static void fmd_process_fm_function(
- uint8_t *packet_buffer
- )
+static void fmd_process_fm_function(u8 *packet_buffer)
{
switch (packet_buffer[0]) {
case FM_FUNCTION_ENABLE:
{
- FM_DEBUG_REPORT("FM_FUNCTION_ENABLE ,"\
- "command successed received");
- os_set_cmd_sem();
+ FM_DEBUG_REPORT("FM_FUNCTION_ENABLE ,"
+ "command success received");
+ os_set_cmd_sem();
}
break;
case FM_FUNCTION_DISABLE:
{
- FM_DEBUG_REPORT("FM_FUNCTION_DISABLE ,"\
- "command successed received");
- os_set_cmd_sem();
+ FM_DEBUG_REPORT("FM_FUNCTION_DISABLE ,"
+ "command success received");
+ os_set_cmd_sem();
}
break;
case FM_FUNCTION_RESET:
{
- FM_DEBUG_REPORT("FM_FUNCTION_RESET ,"\
- "command successed received");
- os_set_cmd_sem();
+ FM_DEBUG_REPORT("FM_FUNCTION_RESET ,"
+ "command success received");
+ os_set_cmd_sem();
}
break;
case FM_FUNCTION_WRITECOMMAND:
{
/* flip the header bits to take into account
- * of little endian format */
+ * of little endian format */
fmd_data.cmd_id = packet_buffer[2] << 8 |
- packet_buffer[1];
- fmd_data.num_parameters = fmd_data.cmd_id & 0x07;
+ packet_buffer[1];
+ fmd_data.num_parameters = fmd_data.cmd_id & 0x07;
fmd_data.cmd_id = fmd_data.cmd_id >> 3;
- if (fmd_data.num_parameters) {
+ if (fmd_data.num_parameters) {
fmd_data.parameters = &packet_buffer[3];
- os_mem_copy(fmd_data.parameters ,
- &packet_buffer[3] ,
- fmd_data.num_parameters * 2);
+ os_mem_copy(fmd_data.parameters,
+ &packet_buffer[3],
+ fmd_data.num_parameters * 2);
}
/* Release the semaphore so that upper layer
- * can process the received event */
+ * can process the received event */
os_set_read_response_sem();
}
break;
@@ -821,9 +837,9 @@ static void fmd_process_fm_function(
break;
case FM_FUNCTION_GETINTMASKALL:
{
- FM_DEBUG_REPORT("FM_FUNCTION_GETINTMASKALL ,"\
- "command successed received");
- os_set_cmd_sem();
+ FM_DEBUG_REPORT("FM_FUNCTION_GETINTMASKALL ,"
+ "command success received");
+ os_set_cmd_sem();
}
break;
@@ -831,54 +847,50 @@ static void fmd_process_fm_function(
break;
case FM_FUNCTION_GETINTMASK:
{
- FM_DEBUG_REPORT("FM_FUNCTION_GETINTMASK ,"\
- "command successed received");
- os_set_cmd_sem();
+ FM_DEBUG_REPORT("FM_FUNCTION_GETINTMASK ,"
+ "command success received");
+ os_set_cmd_sem();
}
break;
case FM_FUNCTION_FMFWDOWNLOAD:
{
- FM_DEBUG_REPORT("fmd_process_fm_function: "\
- "FM_FUNCTION_FMFWDOWNLOAD,"\
- "Block Id = %02x",
- packet_buffer[1]);
+ FM_DEBUG_REPORT("fmd_process_fm_function: "
+ "FM_FUNCTION_FMFWDOWNLOAD,"
+ "Block Id = %02x", packet_buffer[1]);
os_set_cmd_sem();
}
break;
default:
{
- FM_DEBUG_REPORT("fmd_process_fm_function: "\
- "default case, FM Func = %d",
- packet_buffer[0]);
+ FM_DEBUG_REPORT("fmd_process_fm_function: "
+ "default case, FM Func = %d",
+ packet_buffer[0]);
}
break;
}
}
/**
- * fmd_st_write_file_block() - download firmware.
+ * fmd_write_file_block() - download firmware.
* This Function adds the header for downloading
* the firmware and coeffecient files and sends it to Protocol Driver.
* @file_block_id: Block ID of the F/W to be transmitted to FM Chip
- * @file_block: Pointer to the buffer containing the bytes to be sent.
+ * @file_block: Buffer containing the bytes to be sent.
* @file_block_length: Size of the Firmware buffer.
*/
-static unsigned int fmd_st_write_file_block(
- uint32_t file_block_id,
- uint8_t *file_block,
- uint16_t file_block_length
- )
+static u8 fmd_write_file_block(u32 file_block_id,
+ u8 *file_block, u16 file_block_length)
{
- unsigned int err = 0;
+ u8 err = 0;
file_block[0] = HCI_PACKET_INDICATOR_FM_CMD_EVT;
file_block[1] = file_block_length + 4;
file_block[2] = CATENA_OPCODE;
- file_block[3] = FM_WRITE ;
- file_block[4] = FM_FUNCTION_FMFWDOWNLOAD ;
- file_block[5] = file_block_id ;
+ file_block[3] = FM_WRITE;
+ file_block[4] = FM_FUNCTION_FMFWDOWNLOAD;
+ file_block[5] = file_block_id;
/* Send the Packet */
err = ste_fm_send_packet(file_block_length + 6, file_block);
@@ -890,763 +902,527 @@ static unsigned int fmd_st_write_file_block(
/* ------------------ External function definitions ---------------------- */
-uint8_t fmd_init(
- void **context
- )
+void fmd_isr(void)
+{
+ int index = 0;
+
+ FM_DEBUG_REPORT("+fmd_isr");
+
+ if (fmd_state_info.interrupt_available_for_processing == STE_FALSE &&
+ fmd_state_info.fmd_initalized == STE_TRUE) {
+ FM_DEBUG_REPORT("fmd_isr: Waiting on irq sem "
+ "interrupt_available_for_processing = %d "
+ "fmd_state_info.fmd_initalized = %d",
+ fmd_state_info.
+ interrupt_available_for_processing,
+ fmd_state_info.fmd_initalized);
+ os_get_interrupt_sem();
+ FM_DEBUG_REPORT("fmd_isr: Waiting on irq sem "
+ "interrupt_available_for_processing = %d "
+ "fmd_state_info.fmd_initalized = %d",
+ fmd_state_info.
+ interrupt_available_for_processing,
+ fmd_state_info.fmd_initalized);
+ }
+
+ if (fmd_state_info.interrupt_available_for_processing == STE_TRUE
+ && fmd_state_info.fmd_initalized == STE_TRUE) {
+ while (index < MAX_COUNT_OF_IRQS) {
+ if (fmd_state_info.interrupt_queue[index]
+ != IRPT_INVALID) {
+ FM_DEBUG_REPORT("fmd_process_interrupt "
+ "Interrupt = %04x",
+ fmd_state_info.
+ interrupt_queue[index]);
+ fmd_process_interrupt(fmd_state_info.
+ interrupt_queue[index]);
+ fmd_state_info.interrupt_queue[index]
+ = IRPT_INVALID;
+ }
+ index++;
+ }
+ }
+ fmd_state_info.interrupt_available_for_processing = STE_FALSE;
+
+ FM_DEBUG_REPORT("-fmd_isr");
+}
+
+u8 fmd_init(void **context)
{
int err = FMD_RESULT_FEATURE_UNSUPPORTED;
*context = (void *)&fmd_state_info;
- fmd_state_info.logginglevel = 2;
-
- fmd_criticalsection_enter();
if (os_fm_driver_init() == 0) {
- g_fmd_initalized = STE_TRUE;
- fmd_state_info.mode = FMD_MODE_IDLE;
- fmd_state_info.rx_freqrange = FMD_FREQRANGE_FMEUROAMERICA;
- fmd_state_info.rx_grid = FMD_GRID_100KHZ;
- fmd_state_info.rx_stereomode = FMD_STEREOMODE_AUTO;
- fmd_state_info.rx_volume = 20;
- fmd_state_info.rx_balance = 0;
- fmd_state_info.rx_mute = STE_FALSE;
+ memset(&fmd_state_info, 0, sizeof(fmd_state_info));
+ fmd_state_info.fmd_initalized = STE_TRUE;
+ fmd_state_info.gocmd = FMD_STATE_NONE;
+ fmd_state_info.callback = NULL;
+ fmd_state_info.rx_freqrange = FMD_FREQRANGE_EUROAMERICA;
+ fmd_state_info.rx_stereomode = FMD_STEREOMODE_BLENDING;
+ fmd_state_info.rx_volume = MAX_ANALOG_VOLUME;
fmd_state_info.rx_antenna = FMD_ANTENNA_EMBEDDED;
- fmd_state_info.rx_deemphasis = FMD_EMPHASIS_75US;
fmd_state_info.rx_rdson = STE_FALSE;
- fmd_state_info.rx_seek_stoplevel = 0x0100;
- fmd_state_info.gocmd = fmd_gocmd_none;
- fmd_state_info.callback = NULL;
+ fmd_state_info.rx_seek_stoplevel = DEFAULT_RSSI_THRESHOLD;
+ fmd_state_info.tx_freqrange = FMD_FREQRANGE_EUROAMERICA;
+ fmd_state_info.tx_preemphasis = FMD_EMPHASIS_75US;
+ fmd_state_info.tx_pilotdev = DEFAULT_PILOT_DEVIATION;
+ fmd_state_info.tx_rdsdev = DEFAULT_RDS_DEVIATION;
+ fmd_state_info.tx_strength = MAX_POWER_LEVEL;
+ fmd_state_info.max_channels_to_scan = DEFAULT_CHANNELS_TO_SCAN;
+ fmd_state_info.tx_stereomode = STE_TRUE;
+ fmd_state_info.irq_index = 0;
err = FMD_RESULT_SUCCESS;
- } else
+ } else {
err = FMD_RESULT_IO_ERROR;
- fmd_criticalsection_leave();
+ }
FM_DEBUG_REPORT("fmd_init returning = %d", err);
return err;
}
-uint8_t fmd_register_callback(
- void *context,
- fmd_radio_cb callback
- )
+void fmd_deinit(void)
{
- struct fmd_state_info_s *state = (struct fmd_state_info_s *)context;
- int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
-
- if (fmd_go_cmd_busy())
- err = FMD_RESULT_BUSY;
- else if (g_fmd_initalized) {
- state->callback = callback;
- err = FMD_RESULT_SUCCESS;
- } else
- err = FMD_RESULT_IO_ERROR;
-
- fmd_criticalsection_leave();
- return err;
+ os_set_interrupt_sem();
+ os_fm_driver_deinit();
+ memset(&fmd_state_info, 0, sizeof(fmd_state_info));
}
-uint8_t fmd_get_version(
- void *context,
- uint16_t version[]
- )
+u8 fmd_register_callback(void *context, fmd_radio_cb callback)
{
+ struct fmd_state_info_t *state = (struct fmd_state_info_t *)context;
int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
- if (fmd_go_cmd_busy())
+ if (fmd_go_cmd_busy()) {
err = FMD_RESULT_BUSY;
- else if (g_fmd_initalized) {
- unsigned int IOresult;
- unsigned int response_count;
- unsigned short response_data[32];
-
- IOresult = fmd_send_cmd_and_read_resp(CMD_GEN_GETVERSION, 0,
- NULL, &response_count, response_data);
- if (IOresult != FMD_RESULT_SUCCESS) {
- err = IOresult;
- } else {
- os_mem_copy(version, response_data,
- sizeof(unsigned short)*7);
- err = FMD_RESULT_SUCCESS;
- }
- } else
- err = FMD_RESULT_IO_ERROR;
-
- fmd_criticalsection_leave();
-
- return err;
-}
-
-uint8_t fmd_set_mode(
- void *context,
- uint8_t mode
- )
-{
- struct fmd_state_info_s *state = (struct fmd_state_info_s *)context;
- int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- unsigned int IOresult;
- unsigned int response_count;
- unsigned short response_data[32];
- fmd_criticalsection_enter();
- if (g_fmd_initalized) {
- unsigned short parameters[1];
- switch (mode) {
- case FMD_MODE_RX:
- parameters[0] = 0x01;
- break;
- case FMD_MODE_TX:
- parameters[0] = 0x02;
- break;
- case FMD_MODE_IDLE:
- default:
- parameters[0] = 0x00;
- break;
- }
-
- IOresult = fmd_send_cmd_and_read_resp(CMD_GEN_GOTOMODE, 1,
- parameters, &response_count, response_data);
- if (IOresult != FMD_RESULT_SUCCESS) {
- err = IOresult;
- } else {
- state->mode = mode;
- state->gocmd = fmd_gocmd_setmode;
- err = FMD_RESULT_WAIT;
- }
- } else
+ } else if (fmd_state_info.fmd_initalized) {
+ state->callback = callback;
+ err = FMD_RESULT_SUCCESS;
+ } else {
err = FMD_RESULT_IO_ERROR;
+ }
- fmd_criticalsection_leave();
return err;
}
-uint8_t fmd_get_mode(
- void *context,
- uint8_t *mode
- )
+u8 fmd_get_version(void *context, u16 version[7]
+ )
{
int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
- if (fmd_go_cmd_busy())
+ if (fmd_go_cmd_busy()) {
err = FMD_RESULT_BUSY;
- else if (g_fmd_initalized) {
- unsigned int IOresult;
- unsigned int response_count;
- unsigned short response_data[8];
- IOresult = fmd_send_cmd_and_read_resp(CMD_GEN_GETMODE, 0,
- NULL, &response_count, response_data);
- if (IOresult != FMD_RESULT_SUCCESS) {
- err = IOresult;
+ } else if (fmd_state_info.fmd_initalized) {
+ u8 io_result;
+ u16 response_count;
+ u16 response_data[32];
+
+ io_result = fmd_send_cmd_and_read_resp(CMD_GEN_GETVERSION, 0,
+ NULL, &response_count,
+ response_data);
+ if (io_result != FMD_RESULT_SUCCESS) {
+ err = io_result;
} else {
- switch (response_data[0]) {
- case 0x00:
- default:
- *mode = FMD_MODE_IDLE;
- break;
- case 0x01:
- *mode = FMD_MODE_RX;
- break;
- case 0x02:
- *mode = FMD_MODE_TX;
- break;
- }
+ os_mem_copy(version, response_data, sizeof(u16) * 7);
err = FMD_RESULT_SUCCESS;
}
- } else
+ } else {
err = FMD_RESULT_IO_ERROR;
-
- fmd_criticalsection_leave();
+ }
return err;
}
-uint8_t fmd_is_freq_range_supported(
- void *context,
- uint8_t range,
- bool *supported
- )
+u8 fmd_set_mode(void *context, u8 mode)
{
+ struct fmd_state_info_t *state = (struct fmd_state_info_t *)context;
int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
-
- if (fmd_go_cmd_busy())
- err = FMD_RESULT_BUSY;
- else if (g_fmd_initalized) {
- switch (range) {
- case FMD_FREQRANGE_FMEUROAMERICA:
- case FMD_FREQRANGE_FMJAPAN:
- case FMD_FREQRANGE_FMCHINA:
- *supported = STE_TRUE;
- break;
- default:
- *supported = STE_FALSE;
- break;
+ u8 io_result;
+ u16 response_count;
+ u16 response_data[32];
+
+ if (mode > FMD_MODE_TX) {
+ err = FMD_RESULT_PARAMETER_INVALID;
+ } else if (fmd_state_info.fmd_initalized) {
+ u16 parameters[1];
+ parameters[0] = mode;
+
+ state->gocmd = FMD_STATE_MODE;
+ io_result = fmd_send_cmd_and_read_resp(CMD_GEN_GOTOMODE, 1,
+ parameters,
+ &response_count,
+ response_data);
+ if (io_result != FMD_RESULT_SUCCESS) {
+ state->gocmd = FMD_STATE_NONE;
+ err = io_result;
+ } else {
+ os_get_cmd_sem();
+ err = FMD_RESULT_SUCCESS;
}
-
- err = FMD_RESULT_SUCCESS;
- } else
+ } else {
err = FMD_RESULT_IO_ERROR;
+ }
- fmd_criticalsection_leave();
return err;
}
-uint8_t fmd_get_freq_range_properties(
- void *context,
- uint8_t range,
- uint32_t *minfreq,
- uint32_t *maxfreq,
- uint32_t *freqinterval
- )
+u8 fmd_get_freq_range_properties(void *context,
+ u8 range, u32 *minfreq, u32 *maxfreq)
{
int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
- if (fmd_go_cmd_busy())
+ if (fmd_go_cmd_busy()) {
err = FMD_RESULT_BUSY;
- else if (g_fmd_initalized) {
- switch (range) {
- case FMD_FREQRANGE_FMEUROAMERICA:
- *minfreq = 87500;
+ } else if (fmd_state_info.fmd_initalized) {
+ switch (range) {
+ case FMD_FREQRANGE_EUROAMERICA:
+ *minfreq = 87500;
*maxfreq = 108000;
- *freqinterval = 50;
break;
- case FMD_FREQRANGE_FMJAPAN:
+ case FMD_FREQRANGE_JAPAN:
*minfreq = 76000;
*maxfreq = 90000;
- *freqinterval = 50;
break;
- case FMD_FREQRANGE_FMCHINA:
- *minfreq = 70000;
+ case FMD_FREQRANGE_CHINA:
+ *minfreq = 70000;
*maxfreq = 108000;
- *freqinterval = 100;
break;
default:
break;
}
err = FMD_RESULT_SUCCESS;
- } else
+ } else {
err = FMD_RESULT_IO_ERROR;
+ }
- fmd_criticalsection_leave();
return err;
}
-uint8_t fmd_set_antenna(
- void *context,
- uint8_t ant
- )
+u8 fmd_set_antenna(void *context, u8 antenna)
{
- struct fmd_state_info_s *state = (struct fmd_state_info_s *)context;
+ struct fmd_state_info_t *state = (struct fmd_state_info_t *)context;
int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
- if (fmd_go_cmd_busy())
+ if (fmd_go_cmd_busy()) {
err = FMD_RESULT_BUSY;
- else if (g_fmd_initalized) {
- unsigned int IOresult;
- unsigned short parameters[1];
- unsigned int response_count;
- unsigned short response_data[32];
-
- switch (ant) {
- case FMD_ANTENNA_EMBEDDED:
- parameters[0] = 0x0000;
- break;
- case FMD_ANTENNA_WIRED:
- default:
- parameters[0] = 0x0001;
- break;
- }
-
- IOresult = fmd_send_cmd_and_read_resp(CMD_FMR_SETANTENNA, 1,
- parameters, &response_count, response_data);
- if (IOresult != FMD_RESULT_SUCCESS) {
- err = IOresult;
+ } else if (antenna > FMD_ANTENNA_WIRED) {
+ err = FMD_RESULT_PARAMETER_INVALID;
+ } else if (fmd_state_info.fmd_initalized) {
+ u8 io_result;
+ u16 parameters[1];
+ u16 response_count;
+ u16 response_data[32];
+
+ parameters[0] = antenna;
+
+ state->gocmd |= FMD_STATE_ANTENNA;
+ io_result = fmd_send_cmd_and_read_resp(CMD_FMR_SETANTENNA, 1,
+ parameters,
+ &response_count,
+ response_data);
+ if (io_result != FMD_RESULT_SUCCESS) {
+ state->gocmd = FMD_STATE_NONE;
+ err = io_result;
} else {
- state->rx_antenna = ant;
- state->gocmd = fmd_gocmd_setantenna;
- err = FMD_RESULT_WAIT;
+ state->rx_antenna = antenna;
+ os_get_cmd_sem();
+ err = FMD_RESULT_SUCCESS;
}
- } else
+ } else {
err = FMD_RESULT_IO_ERROR;
+ }
- fmd_criticalsection_leave();
return err;
}
-uint8_t fmd_get_antenna(
- void *context,
- uint8_t *ant
- )
+u8 fmd_get_antenna(void *context, u8 * antenna)
{
- struct fmd_state_info_s *state = (struct fmd_state_info_s *)context;
+ struct fmd_state_info_t *state = (struct fmd_state_info_t *)context;
int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
- if (fmd_go_cmd_busy())
+ if (fmd_go_cmd_busy()) {
err = FMD_RESULT_BUSY;
- else if (g_fmd_initalized) {
- *ant = state->rx_antenna;
+ } else if (fmd_state_info.fmd_initalized) {
+ *antenna = state->rx_antenna;
err = FMD_RESULT_SUCCESS;
- } else
+ } else {
err = FMD_RESULT_IO_ERROR;
+ }
- fmd_criticalsection_leave();
return err;
}
-uint8_t fmd_set_freq_range(
- void *context,
- uint8_t range
- )
+u8 fmd_set_freq_range(void *context, u8 range)
{
- struct fmd_state_info_s *state = (struct fmd_state_info_s *)context;
+ struct fmd_state_info_t *state = (struct fmd_state_info_t *)context;
int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
- if (fmd_go_cmd_busy())
+ if (fmd_go_cmd_busy()) {
err = FMD_RESULT_BUSY;
- else if (g_fmd_initalized) {
- unsigned int IOresult;
- unsigned short parameters[8];
- unsigned int response_count;
- unsigned short response_data[8];
-
+ } else if (range > FMD_FREQRANGE_CHINA) {
+ err = FMD_RESULT_PARAMETER_INVALID;
+ } else if (fmd_state_info.fmd_initalized) {
+ u8 io_result;
+ u16 parameters[8];
+ u16 response_count;
+ u16 response_data[8];
+
+ parameters[0] = range;
parameters[1] = 0;
parameters[2] = 760;
- switch (range) {
- case FMD_FREQRANGE_FMEUROAMERICA:
- default:
- parameters[0] = 0;
- break;
- case FMD_FREQRANGE_FMJAPAN:
- parameters[0] = 1;
- break;
- case FMD_FREQRANGE_FMCHINA:
- parameters[0] = 2;
- break;
- }
- IOresult = fmd_send_cmd_and_read_resp(CMD_FMR_TN_SETBAND, 3,
- parameters, &response_count, response_data);
- if (IOresult != FMD_RESULT_SUCCESS) {
- err = IOresult;
+ io_result = fmd_send_cmd_and_read_resp(CMD_FMR_TN_SETBAND, 3,
+ parameters,
+ &response_count,
+ response_data);
+ if (io_result != FMD_RESULT_SUCCESS) {
+ err = io_result;
} else {
state->rx_freqrange = range;
- fmd_callback((void *)&fmd_state_info,
- FMD_EVENT_FREQUENCY_RANGE_CHANGED ,
- 0, STE_FALSE);
err = FMD_RESULT_SUCCESS;
}
- } else
+ } else {
err = FMD_RESULT_IO_ERROR;
+ }
- fmd_criticalsection_leave();
return err;
}
-uint8_t fmd_get_freq_range(
- void *context,
- uint8_t *range
- )
+u8 fmd_get_freq_range(void *context, u8 * range)
{
- struct fmd_state_info_s *state = (struct fmd_state_info_s *)context;
+ struct fmd_state_info_t *state = (struct fmd_state_info_t *)context;
int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
if (fmd_go_cmd_busy())
err = FMD_RESULT_BUSY;
- else if (g_fmd_initalized) {
+ else if (fmd_state_info.fmd_initalized) {
*range = state->rx_freqrange;
err = FMD_RESULT_SUCCESS;
} else
err = FMD_RESULT_IO_ERROR;
- fmd_criticalsection_leave();
- return err;
-}
-
-uint8_t fmd_rx_set_grid(
- void *context,
- uint8_t grid
- )
-{
- struct fmd_state_info_s *state = (struct fmd_state_info_s *)context;
- int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
-
- if (fmd_go_cmd_busy())
- err = FMD_RESULT_BUSY;
- else if (g_fmd_initalized) {
- unsigned int IOresult;
- unsigned short parameters[1];
- unsigned int response_count;
- unsigned short response_data[32];
-
- switch (grid) {
- case FMD_GRID_50KHZ:
- default:
- parameters[0] = 0;
- break;
- case FMD_GRID_100KHZ:
- parameters[0] = 1;
- break;
- case FMD_GRID_200KHZ:
- parameters[0] = 2;
- break;
- }
-
- IOresult = fmd_send_cmd_and_read_resp(CMD_FMR_TN_SETGRID, 1,
- parameters, &response_count, response_data);
- if (IOresult != FMD_RESULT_SUCCESS) {
- err = IOresult;
- } else {
- state->rx_grid = grid;
- err = FMD_RESULT_SUCCESS;
- }
- } else
- err = FMD_RESULT_IO_ERROR;
-
- fmd_criticalsection_leave();
- return err;
-}
-
-uint8_t fmd_rx_get_grid(
- void *context,
- uint8_t *grid
- )
-{
- struct fmd_state_info_s *state = (struct fmd_state_info_s *)context;
- int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
-
- if (fmd_go_cmd_busy())
- err = FMD_RESULT_BUSY;
- else if (g_fmd_initalized) {
- *grid = state->rx_grid;
- err = FMD_RESULT_SUCCESS;
- } else
- err = FMD_RESULT_IO_ERROR;
-
- fmd_criticalsection_leave();
return err;
}
-uint8_t fmd_rx_set_deemphasis(
- void *context,
- uint8_t deemphasis
- )
+u8 fmd_rx_set_grid(void *context, u8 grid)
{
- struct fmd_state_info_s *state = (struct fmd_state_info_s *)context;
int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
- if (fmd_go_cmd_busy())
+ if (fmd_go_cmd_busy()) {
err = FMD_RESULT_BUSY;
- else if (g_fmd_initalized) {
- unsigned int IOresult;
- unsigned short parameters[1];
- unsigned int response_count;
- unsigned short response_data[32];
-
- switch (deemphasis) {
- case FMD_EMPHASIS_50US:
- parameters[0] = 1;
- break;
- case FMD_EMPHASIS_75US:
- default:
- parameters[0] = 2;
- break;
- }
-
- IOresult = fmd_send_cmd_and_read_resp(CMD_FMR_RP_SETDEEMPHASIS,
- 1, parameters, &response_count,
- response_data);
- if (IOresult != FMD_RESULT_SUCCESS) {
- err = IOresult;
- } else {
- state->rx_deemphasis = deemphasis;
+ } else if (grid > FMD_GRID_200KHZ) {
+ err = FMD_RESULT_PARAMETER_INVALID;
+ } else if (fmd_state_info.fmd_initalized) {
+ u8 io_result;
+ u16 parameters[1];
+ u16 response_count;
+ u16 response_data[32];
+
+ parameters[0] = grid;
+
+ io_result = fmd_send_cmd_and_read_resp(CMD_FMR_TN_SETGRID, 1,
+ parameters,
+ &response_count,
+ response_data);
+ if (io_result != FMD_RESULT_SUCCESS)
+ err = io_result;
+ else
err = FMD_RESULT_SUCCESS;
- }
- } else
- err = FMD_RESULT_IO_ERROR;
-
- fmd_criticalsection_leave();
- return err;
-}
-
-uint8_t fmd_rx_get_deemphasis(
- void *context,
- uint8_t *deemphasis
- )
-{
- struct fmd_state_info_s *state = (struct fmd_state_info_s *)context;
- int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
-
- if (fmd_go_cmd_busy())
- err = FMD_RESULT_BUSY;
- else if (g_fmd_initalized) {
- *deemphasis = state->rx_deemphasis;
- err = FMD_RESULT_SUCCESS;
- } else
+ } else {
err = FMD_RESULT_IO_ERROR;
+ }
- fmd_criticalsection_leave();
return err;
}
-uint8_t fmd_rx_set_frequency(
- void *context,
- uint32_t freq
- )
+u8 fmd_rx_set_frequency(void *context, u32 freq)
{
- struct fmd_state_info_s *state = (struct fmd_state_info_s *)context;
+ struct fmd_state_info_t *state = (struct fmd_state_info_t *)context;
int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
- if (fmd_go_cmd_busy())
+ if (fmd_go_cmd_busy()) {
err = FMD_RESULT_BUSY;
- else if (g_fmd_initalized) {
- unsigned int IOresult;
- unsigned short parameters[1];
- unsigned int response_count;
- unsigned short response_data[8];
+ } else if (fmd_state_info.fmd_initalized) {
+ u8 io_result;
+ u16 parameters[1];
+ u16 response_count;
+ u16 response_data[8];
parameters[0] = fmd_rx_frequency_to_channel(context, freq);
- IOresult = fmd_send_cmd_and_read_resp(
- CMD_FMR_SP_TUNE_SETCHANNEL,
- 1, parameters, &response_count, response_data);
- if (IOresult != FMD_RESULT_SUCCESS) {
- err = IOresult;
+ state->gocmd |= FMD_STATE_FREQUENCY;
+ io_result =
+ fmd_send_cmd_and_read_resp(CMD_FMR_SP_TUNE_SETCHANNEL, 1,
+ parameters, &response_count,
+ response_data);
+ if (io_result != FMD_RESULT_SUCCESS) {
+ state->gocmd = FMD_STATE_NONE;
+ err = io_result;
} else {
- state->gocmd = fmd_gocmd_setfrequency;
- err = FMD_RESULT_WAIT;
+ os_get_cmd_sem();
+ err = FMD_RESULT_SUCCESS;
}
- } else
+ } else {
err = FMD_RESULT_IO_ERROR;
+ }
- fmd_criticalsection_leave();
return err;
}
-uint8_t fmd_rx_get_frequency(
- void *context,
- uint32_t *freq
- )
+u8 fmd_rx_get_frequency(void *context, u32 * freq)
{
int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
- if (fmd_go_cmd_busy())
+ if (fmd_go_cmd_busy()) {
err = FMD_RESULT_BUSY;
- else if (g_fmd_initalized) {
- unsigned int IOresult;
- unsigned int response_count;
- unsigned short response_data[32];
-
- IOresult = fmd_send_cmd_and_read_resp(
- CMD_FMR_SP_TUNE_GETCHANNEL,
- 0, NULL, &response_count, response_data);
- if (IOresult != FMD_RESULT_SUCCESS) {
- err = IOresult;
+ } else if (fmd_state_info.fmd_initalized) {
+ u8 io_result;
+ u16 response_count;
+ u16 response_data[32];
+
+ io_result =
+ fmd_send_cmd_and_read_resp(CMD_FMR_SP_TUNE_GETCHANNEL, 0,
+ NULL, &response_count,
+ response_data);
+ if (io_result != FMD_RESULT_SUCCESS) {
+ err = io_result;
} else {
*freq = fmd_rx_channel_to_frequency(context,
- response_data[0]);
+ response_data[0]);
err = FMD_RESULT_SUCCESS;
}
- } else
+ } else {
err = FMD_RESULT_IO_ERROR;
+ }
- fmd_criticalsection_leave();
return err;
}
-uint8_t fmd_rx_set_stereo_mode(
- void *context,
- uint32_t mode
- )
+u8 fmd_rx_set_stereo_mode(void *context, u8 mode)
{
- struct fmd_state_info_s *state = (struct fmd_state_info_s *)context;
+ struct fmd_state_info_t *state = (struct fmd_state_info_t *)context;
int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
- if (fmd_go_cmd_busy())
+ if (fmd_go_cmd_busy()) {
err = FMD_RESULT_BUSY;
- else if (g_fmd_initalized) {
- unsigned int IOresult;
- unsigned short parameters[8];
- unsigned int response_count;
- unsigned short response_data[32];
-
- switch (mode) {
- case FMD_STEREOMODE_MONO:
- parameters[0] = 1;
- break;
- case FMD_STEREOMODE_STEREO:
- parameters[0] = 0;
- break;
- case FMD_STEREOMODE_AUTO:
- parameters[0] = 2;
- break;
- }
-
- IOresult = fmd_send_cmd_and_read_resp(CMD_FMR_RP_STEREO_SETMODE,
- 1, parameters, &response_count, response_data);
- if (IOresult != FMD_RESULT_SUCCESS) {
- err = IOresult;
+ } else if (mode > FMD_STEREOMODE_BLENDING) {
+ err = FMD_RESULT_PARAMETER_INVALID;
+ } else if (fmd_state_info.fmd_initalized) {
+ u8 io_result;
+ u16 parameters[8];
+ u16 response_count;
+ u16 response_data[32];
+
+ parameters[0] = mode;
+
+ io_result =
+ fmd_send_cmd_and_read_resp(CMD_FMR_RP_STEREO_SETMODE, 1,
+ parameters, &response_count,
+ response_data);
+ if (io_result != FMD_RESULT_SUCCESS) {
+ err = io_result;
} else {
state->rx_stereomode = mode;
err = FMD_RESULT_SUCCESS;
}
- } else
+ } else {
err = FMD_RESULT_IO_ERROR;
+ }
- fmd_criticalsection_leave();
return err;
}
-uint8_t fmd_rx_get_stereo_mode(
- void *context,
- uint32_t *mode
- )
+u8 fmd_rx_get_stereo_mode(void *context, u8 * mode)
{
- struct fmd_state_info_s *state = (struct fmd_state_info_s *)context;
+ struct fmd_state_info_t *state = (struct fmd_state_info_t *)context;
int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
- if (fmd_go_cmd_busy())
+ if (fmd_go_cmd_busy()) {
err = FMD_RESULT_BUSY;
- else if (g_fmd_initalized) {
+ } else if (fmd_state_info.fmd_initalized) {
*mode = state->rx_stereomode;
err = FMD_RESULT_SUCCESS;
- } else
+ } else {
err = FMD_RESULT_IO_ERROR;
+ }
- fmd_criticalsection_leave();
return err;
}
-uint8_t fmd_rx_get_signal_strength(
- void *context,
- uint32_t *strength
- )
+u8 fmd_rx_get_signal_strength(void *context, u16 * strength)
{
int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
- if (fmd_go_cmd_busy())
+ if (fmd_go_cmd_busy()) {
err = FMD_RESULT_BUSY;
- else if (g_fmd_initalized) {
- unsigned int IOresult;
- unsigned int response_count;
- unsigned short response_data[8];
-
- IOresult = fmd_send_cmd_and_read_resp(CMD_FMR_RP_GETRSSI,
- 0, NULL, &response_count, response_data);
- if (IOresult != FMD_RESULT_SUCCESS) {
- err = IOresult;
+ } else if (fmd_state_info.fmd_initalized) {
+ u8 io_result;
+ u16 response_count;
+ u16 response_data[8];
+
+ io_result = fmd_send_cmd_and_read_resp(CMD_FMR_RP_GETRSSI,
+ 0, NULL, &response_count,
+ response_data);
+ if (io_result != FMD_RESULT_SUCCESS) {
+ err = io_result;
} else {
*strength = response_data[0];
err = FMD_RESULT_SUCCESS;
}
- } else
- err = FMD_RESULT_IO_ERROR;
- fmd_criticalsection_leave();
- return err;
-}
-
-uint8_t fmd_rx_get_pilot_state(
- void *context,
- bool *on
- )
-{
- int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
-
- if (fmd_go_cmd_busy())
- err = FMD_RESULT_BUSY;
- else if (g_fmd_initalized) {
- unsigned int IOresult;
- unsigned int response_count;
- unsigned short response_data[8];
-
- IOresult = fmd_send_cmd_and_read_resp(CMD_FMR_RP_GETSTATE,
- 0, NULL, &response_count, response_data);
- if (IOresult != FMD_RESULT_SUCCESS) {
- err = IOresult;
- } else {
- *on = (response_data[0] == 0x0001);
- err = FMD_RESULT_SUCCESS;
- }
- } else
+ } else {
err = FMD_RESULT_IO_ERROR;
+ }
- fmd_criticalsection_leave();
return err;
}
-uint8_t fmd_rx_set_stop_level(
- void *context,
- uint16_t stoplevel
- )
+u8 fmd_rx_set_stop_level(void *context, u16 stoplevel)
{
- struct fmd_state_info_s *state = (struct fmd_state_info_s *)context;
+ struct fmd_state_info_t *state = (struct fmd_state_info_t *)context;
int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
- if (fmd_go_cmd_busy())
+ if (fmd_go_cmd_busy()) {
err = FMD_RESULT_BUSY;
- else if (g_fmd_initalized) {
+ } else if (fmd_state_info.fmd_initalized) {
state->rx_seek_stoplevel = stoplevel;
err = FMD_RESULT_SUCCESS;
- } else
+ } else {
err = FMD_RESULT_IO_ERROR;
+ }
- fmd_criticalsection_leave();
return err;
}
-uint8_t fmd_rx_get_stop_level(
- void *context,
- uint16_t *stoplevel
- )
+u8 fmd_rx_get_stop_level(void *context, u16 * stoplevel)
{
- struct fmd_state_info_s *state = (struct fmd_state_info_s *)context;
+ struct fmd_state_info_t *state = (struct fmd_state_info_t *)context;
int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
- if (fmd_go_cmd_busy())
+ if (fmd_go_cmd_busy()) {
err = FMD_RESULT_BUSY;
- else if (g_fmd_initalized) {
+ } else if (fmd_state_info.fmd_initalized) {
*stoplevel = state->rx_seek_stoplevel;
err = FMD_RESULT_SUCCESS;
- } else
+ } else {
err = FMD_RESULT_IO_ERROR;
- fmd_criticalsection_leave();
+ }
+
return err;
}
-uint8_t fmd_rx_seek(
- void *context,
- bool upwards
- )
+u8 fmd_rx_seek(void *context, bool upwards)
{
- struct fmd_state_info_s *state = (struct fmd_state_info_s *)context;
+ struct fmd_state_info_t *state = (struct fmd_state_info_t *)context;
int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
- if (fmd_go_cmd_busy())
+ if (fmd_go_cmd_busy()) {
err = FMD_RESULT_BUSY;
- else if (g_fmd_initalized) {
- unsigned int IOresult;
- unsigned short parameters[8];
- unsigned int response_count;
- unsigned short response_data[32];
+ } else if (fmd_state_info.fmd_initalized) {
+ u8 io_result;
+ u16 parameters[8];
+ u16 response_count;
+ u16 response_data[32];
if (upwards)
parameters[0] = 0x0000;
@@ -1654,87 +1430,106 @@ uint8_t fmd_rx_seek(
parameters[0] = 0x0001;
parameters[1] = state->rx_seek_stoplevel;
parameters[2] = 0x7FFF;
- /*0x7FFF disables "running snr" criterion for search*/
+ /*0x7FFF disables "running snr" criterion for search */
parameters[3] = 0x7FFF;
- /*0x7FFF disables "final snr" criterion for search*/
-
- IOresult = fmd_send_cmd_and_read_resp(CMD_FMR_SP_SEARCH_START,
- 4, parameters, &response_count, response_data);
- if (IOresult != FMD_RESULT_SUCCESS)
- err = IOresult;
- else {
- state->gocmd = fmd_gocmd_seek;
+ /*0x7FFF disables "final snr" criterion for search */
+
+ state->gocmd |= FMD_STATE_SEEK;
+ io_result = fmd_send_cmd_and_read_resp(CMD_FMR_SP_SEARCH_START,
+ 4, parameters,
+ &response_count,
+ response_data);
+ if (io_result != FMD_RESULT_SUCCESS) {
+ state->gocmd = FMD_STATE_NONE;
+ err = io_result;
+ } else {
err = FMD_RESULT_ONGOING;
}
- } else
+ } else {
err = FMD_RESULT_IO_ERROR;
- fmd_criticalsection_leave();
+ }
+
return err;
}
-uint8_t fmd_rx_scan_band(
- void *context
- )
+u8 fmd_rx_scan_band(void *context, u8 max_channels_to_scan)
{
- struct fmd_state_info_s *state = (struct fmd_state_info_s *)context;
+ struct fmd_state_info_t *state = (struct fmd_state_info_t *)context;
int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
- if (fmd_go_cmd_busy())
+ if (fmd_go_cmd_busy()) {
err = FMD_RESULT_BUSY;
- else if (g_fmd_initalized) {
- unsigned int IOresult;
- unsigned short parameters[8];
- unsigned int response_count;
- unsigned short response_data[32];
-
- parameters[0] = 0x0020;
+ } else if (max_channels_to_scan > MAX_CHANNELS_TO_SCAN) {
+ err = FMD_RESULT_PARAMETER_INVALID;
+ } else if (fmd_state_info.fmd_initalized) {
+ u8 io_result;
+ u16 parameters[8];
+ u16 response_count;
+ u16 response_data[32];
+
+ parameters[0] = max_channels_to_scan;
parameters[1] = state->rx_seek_stoplevel;
parameters[2] = 0x7FFF;
parameters[3] = 0x7FFF;
- IOresult = fmd_send_cmd_and_read_resp(CMD_FMR_SP_SCAN_START,
- 4, parameters, &response_count,
- response_data);
- if (IOresult != FMD_RESULT_SUCCESS)
- err = IOresult;
- else {
- state->gocmd = fmd_gocmd_scanband;
+ state->gocmd |= FMD_STATE_SCAN_BAND;
+ state->max_channels_to_scan = max_channels_to_scan;
+ io_result = fmd_send_cmd_and_read_resp(CMD_FMR_SP_SCAN_START,
+ 4, parameters,
+ &response_count,
+ response_data);
+ if (io_result != FMD_RESULT_SUCCESS) {
+ state->gocmd = FMD_STATE_NONE;
+ err = io_result;
+ } else {
err = FMD_RESULT_ONGOING;
}
- } else
+ } else {
err = FMD_RESULT_IO_ERROR;
- fmd_criticalsection_leave();
+ }
+
return err;
}
-uint8_t fmd_rx_get_scan_band_info(
- void *context,
- uint32_t index,
- uint16_t *numchannels,
- uint16_t *channels,
- uint16_t *rssi
- )
+u8 fmd_rx_get_max_channels_to_scan(void *context, u8 *max_channels_to_scan)
{
int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
- if (fmd_go_cmd_busy())
+ if (fmd_go_cmd_busy()) {
+ err = FMD_RESULT_BUSY;
+ } else if (fmd_state_info.fmd_initalized) {
+ *max_channels_to_scan = fmd_state_info.max_channels_to_scan;
+ err = FMD_RESULT_SUCCESS;
+ } else {
+ err = FMD_RESULT_IO_ERROR;
+ }
+
+ return err;
+}
+
+u8 fmd_rx_get_scan_band_info(void *context,
+ u32 index,
+ u16 *numchannels, u16 *channels, u16 *rssi)
+{
+ int err = FMD_RESULT_FEATURE_UNSUPPORTED;
+
+ if (fmd_go_cmd_busy()) {
err = FMD_RESULT_BUSY;
- else if (g_fmd_initalized) {
- unsigned int IOresult;
- unsigned short parameters[1];
- unsigned int response_count;
- unsigned short response_data[32];
+ } else if (fmd_state_info.fmd_initalized) {
+ u8 io_result;
+ u16 parameters[1];
+ u16 response_count;
+ u16 response_data[32];
parameters[0] = index;
- IOresult = fmd_send_cmd_and_read_resp(
- CMD_FMR_SP_SCAN_GETRESULT, 1,
- parameters, &response_count, response_data);
- if (IOresult != FMD_RESULT_SUCCESS)
- err = IOresult;
- else {
+ io_result =
+ fmd_send_cmd_and_read_resp(CMD_FMR_SP_SCAN_GETRESULT, 1,
+ parameters, &response_count,
+ response_data);
+ if (io_result != FMD_RESULT_SUCCESS) {
+ err = io_result;
+ } else {
*numchannels = response_data[0];
channels[0] = response_data[1];
rssi[0] = response_data[2];
@@ -1744,216 +1539,363 @@ uint8_t fmd_rx_get_scan_band_info(
rssi[2] = response_data[6];
err = FMD_RESULT_SUCCESS;
}
- } else
+ } else {
err = FMD_RESULT_IO_ERROR;
- fmd_criticalsection_leave();
+ }
+
return err;
}
-uint8_t fmd_rx_step_frequency(
- void *context,
- bool upwards
- )
+u8 fmd_rx_block_scan(void *context, u32 start_freq, u32 stop_freq, u8 antenna)
{
- struct fmd_state_info_s *state = (struct fmd_state_info_s *)context;
+ struct fmd_state_info_t *state = (struct fmd_state_info_t *)context;
+ u16 start_channel;
+ u16 stop_channel;
int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
- if (fmd_go_cmd_busy())
+ if (fmd_go_cmd_busy()) {
err = FMD_RESULT_BUSY;
- else if (g_fmd_initalized) {
- unsigned int IOresult;
- unsigned short parameters[1];
- unsigned int response_count;
- unsigned short response_data[8];
+ } else if (fmd_state_info.fmd_initalized) {
+ u8 io_result;
+ u16 parameters[8];
+ u16 response_count;
+ u16 response_data[32];
+ start_channel = fmd_rx_frequency_to_channel(context,
+ start_freq);
+ stop_channel = fmd_rx_frequency_to_channel(context, stop_freq);
+ if (antenna > 1) {
+ err = FMD_RESULT_PARAMETER_INVALID;
+ } else {
+ parameters[0] = start_channel;
+ parameters[1] = stop_channel;
+ parameters[2] = antenna;
+
+ state->gocmd |= FMD_STATE_BLOCK_SCAN;
+ io_result =
+ fmd_send_cmd_and_read_resp
+ (CMD_FMR_SP_BLOCKSCAN_START, 3, parameters,
+ &response_count, response_data);
+ if (io_result != FMD_RESULT_SUCCESS) {
+ state->gocmd = FMD_STATE_NONE;
+ err = io_result;
+ } else {
+ err = FMD_RESULT_ONGOING;
+ }
+ }
+ } else {
+ err = FMD_RESULT_IO_ERROR;
+ }
- if (upwards)
- parameters[0] = 0x0000;
- else
- parameters[0] = 0x0001;
+ return err;
+}
+
+u8 fmd_rx_get_block_scan_result(void *context,
+ u32 index, u16 *numchannels, u16 *rssi)
+{
+ int err = FMD_RESULT_FEATURE_UNSUPPORTED;
+
+ if (fmd_go_cmd_busy()) {
+ err = FMD_RESULT_BUSY;
+ } else if (fmd_state_info.fmd_initalized) {
+ u8 io_result;
+ u16 parameters[1];
+ u16 response_count;
+ u16 response_data[32];
- IOresult = fmd_send_cmd_and_read_resp(
- CMD_FMR_SP_TUNE_STEPCHANNEL,
- 1, parameters, &response_count, response_data);
- if (IOresult != FMD_RESULT_SUCCESS) {
- err = IOresult;
+ parameters[0] = index;
+
+ io_result =
+ fmd_send_cmd_and_read_resp(CMD_FMR_SP_BLOCKSCAN_GETRESULT,
+ 1, parameters, &response_count,
+ response_data);
+ if (io_result != FMD_RESULT_SUCCESS) {
+ err = io_result;
} else {
- state->gocmd = fmd_gocmd_stepfrequency;
- err = FMD_RESULT_WAIT;
+ *numchannels = response_data[0];
+ rssi[0] = response_data[1];
+ rssi[1] = response_data[2];
+ rssi[2] = response_data[3];
+ rssi[3] = response_data[4];
+ rssi[4] = response_data[5];
+ rssi[5] = response_data[6];
+ err = FMD_RESULT_SUCCESS;
}
- } else
+ } else {
err = FMD_RESULT_IO_ERROR;
- fmd_criticalsection_leave();
+ }
+
return err;
}
-uint8_t fmd_rx_stop_seeking(
- void *context
- )
+u8 fmd_rx_stop_seeking(void *context)
{
- struct fmd_state_info_s *state = (struct fmd_state_info_s *)context;
+ struct fmd_state_info_t *state = (struct fmd_state_info_t *)context;
int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
-
- if (g_fmd_initalized) {
- if ((state->gocmd == fmd_gocmd_seek)
- || (state->gocmd == fmd_gocmd_scanband)) {
- unsigned int IOresult;
- unsigned int response_count;
- unsigned short response_data[32];
-
- IOresult = fmd_send_cmd_and_read_resp(
- CMD_FMR_SP_STOP, 0,
- NULL, &response_count, response_data);
- if (IOresult != FMD_RESULT_SUCCESS)
- err = IOresult;
- else {
- state->gocmd = fmd_gocmd_seekstop;
- err = FMD_RESULT_WAIT;
+
+ if (fmd_state_info.fmd_initalized) {
+ if ((state->gocmd & FMD_STATE_SEEK)
+ || (state->gocmd & FMD_STATE_SCAN_BAND)) {
+ u8 io_result;
+ u16 response_count;
+ u16 response_data[32];
+
+ state->gocmd &= ~FMD_STATE_SCAN_BAND;
+ state->gocmd &= ~FMD_STATE_SEEK;
+ state->gocmd |= FMD_STATE_SEEK_STOP;
+ io_result =
+ fmd_send_cmd_and_read_resp(CMD_FMR_SP_STOP, 0, NULL,
+ &response_count,
+ response_data);
+ if (io_result != FMD_RESULT_SUCCESS) {
+ state->gocmd = FMD_STATE_NONE;
+ err = io_result;
+ } else {
+ os_get_cmd_sem();
+ err = FMD_RESULT_SUCCESS;
}
- } else
+ } else {
err = FMD_RESULT_PRECONDITIONS_VIOLATED;
- } else
+ }
+ } else {
err = FMD_RESULT_IO_ERROR;
- fmd_criticalsection_leave();
+ }
+
return err;
}
-uint8_t fmd_rx_get_rds(
- void *context,
- bool *on
- )
+u8 fmd_rx_af_update_start(void *context, u32 freq)
{
+ struct fmd_state_info_t *state = (struct fmd_state_info_t *)context;
int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
- if (fmd_go_cmd_busy())
+ if (fmd_go_cmd_busy()) {
err = FMD_RESULT_BUSY;
- else if (g_fmd_initalized) {
- *on = fmd_state_info.rx_rdson;
- err = FMD_RESULT_SUCCESS;
- } else
+ } else if (fmd_state_info.fmd_initalized) {
+ u8 io_result;
+ u16 parameters[1];
+ u16 response_count;
+ u16 response_data[8];
+
+ parameters[0] = fmd_rx_frequency_to_channel(state, freq);
+
+ state->gocmd |= FMD_STATE_AF_UPDATE;
+ io_result =
+ fmd_send_cmd_and_read_resp(CMD_FMR_SP_AFUPDATE_START, 1,
+ parameters, &response_count,
+ response_data);
+ if (io_result != FMD_RESULT_SUCCESS) {
+ err = io_result;
+ state->gocmd = FMD_STATE_NONE;
+ } else {
+ os_get_cmd_sem();
+ err = FMD_RESULT_SUCCESS;
+ }
+ } else {
err = FMD_RESULT_IO_ERROR;
- fmd_criticalsection_leave();
+ }
+
return err;
}
-uint8_t fmd_rx_query_rds_signal(
- void *context,
- bool *is_signal
- )
+u8 fmd_rx_get_af_update_result(void *context, u16 * af_level)
{
int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
- if (fmd_go_cmd_busy())
+ if (fmd_go_cmd_busy()) {
err = FMD_RESULT_BUSY;
- else if (g_fmd_initalized) {
- unsigned int IOresult;
- unsigned int response_count;
- unsigned short response_data[8];
-
- IOresult = fmd_send_cmd_and_read_resp(CMD_FMR_GETSTATE, 0,
- NULL, &response_count, response_data);
- if (IOresult != FMD_RESULT_SUCCESS)
- err = IOresult;
- else {
- *is_signal = (response_data[3] == 0x0001);
+ } else if (fmd_state_info.fmd_initalized) {
+ u8 io_result;
+ u16 response_count;
+ u16 response_data[32];
+
+ io_result =
+ fmd_send_cmd_and_read_resp(CMD_FMR_SP_AFUPDATE_GETRESULT, 0,
+ NULL, &response_count,
+ response_data);
+
+ if (io_result != FMD_RESULT_SUCCESS) {
+ err = io_result;
+ } else {
+
+ *af_level = response_data[0];
err = FMD_RESULT_SUCCESS;
}
- } else
+ } else {
+ err = FMD_RESULT_IO_ERROR;
+ }
+
+ return err;
+}
+
+u8 fmd_rx_af_switch_start(void *context, u32 freq, u16 picode)
+{
+ struct fmd_state_info_t *state = (struct fmd_state_info_t *)context;
+
+ int err = FMD_RESULT_FEATURE_UNSUPPORTED;
+
+ if (fmd_go_cmd_busy()) {
+ err = FMD_RESULT_BUSY;
+ } else if (fmd_state_info.fmd_initalized) {
+ u8 io_result;
+ u16 parameters[8];
+ u16 response_count;
+ u16 response_data[8];
+
+ parameters[0] = fmd_rx_frequency_to_channel(state, freq);
+ parameters[1] = picode;
+ parameters[2] = 0xFFFF;
+ parameters[3] = state->rx_seek_stoplevel;
+ parameters[4] = 0x0000;
+
+ state->gocmd |= FMD_STATE_AF_SWITCH;
+ io_result =
+ fmd_send_cmd_and_read_resp(CMD_FMR_SP_AFSWITCH_START, 5,
+ parameters, &response_count,
+ response_data);
+ if (io_result != FMD_RESULT_SUCCESS) {
+ state->gocmd = FMD_STATE_NONE;
+ err = io_result;
+ } else {
+ os_get_cmd_sem();
+ err = FMD_RESULT_SUCCESS;
+ }
+ } else {
err = FMD_RESULT_IO_ERROR;
- fmd_criticalsection_leave();
+ }
+
return err;
}
-uint8_t fmd_rx_buffer_set_size(
- void *context,
- uint8_t size
- )
+u8 fmd_rx_get_af_switch_results(void *context,
+ u16 *afs_conclusion,
+ u16 *afs_level, u16 *afs_pi)
{
int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
- if (fmd_go_cmd_busy())
+ if (fmd_go_cmd_busy()) {
+ err = FMD_RESULT_BUSY;
+ } else if (fmd_state_info.fmd_initalized) {
+ u8 io_result;
+ u16 response_count;
+ u16 response_data[32];
+
+ io_result =
+ fmd_send_cmd_and_read_resp(CMD_FMR_SP_AFSWITCH_GETRESULT, 0,
+ NULL, &response_count,
+ response_data);
+
+ if (io_result != FMD_RESULT_SUCCESS) {
+ err = io_result;
+ } else {
+
+ *afs_conclusion = response_data[0];
+ *afs_level = response_data[1];
+ *afs_pi = response_data[2];
+
+ err = FMD_RESULT_SUCCESS;
+ }
+ } else {
+ err = FMD_RESULT_IO_ERROR;
+ }
+
+ return err;
+}
+
+u8 fmd_rx_get_rds(void *context, bool * on)
+{
+ int err = FMD_RESULT_FEATURE_UNSUPPORTED;
+
+ if (fmd_go_cmd_busy()) {
err = FMD_RESULT_BUSY;
- else if (g_fmd_initalized) {
- unsigned int IOresult;
- unsigned short parameters[1];
- unsigned int response_count;
- unsigned short response_data[8];
+ } else if (fmd_state_info.fmd_initalized) {
+ *on = fmd_state_info.rx_rdson;
+ err = FMD_RESULT_SUCCESS;
+ } else {
+ err = FMD_RESULT_IO_ERROR;
+ }
- if (size > 22)
+ return err;
+}
+
+u8 fmd_rx_buffer_set_size(void *context, u8 size)
+{
+ int err = FMD_RESULT_FEATURE_UNSUPPORTED;
+
+ if (fmd_go_cmd_busy()) {
+ err = FMD_RESULT_BUSY;
+ } else if (fmd_state_info.fmd_initalized) {
+ u8 io_result;
+ u16 parameters[1];
+ u16 response_count;
+ u16 response_data[8];
+
+ if (size > MAX_RDS_GROUPS) {
err = FMD_RESULT_IO_ERROR;
- else {
+ } else {
parameters[0] = size;
- IOresult = fmd_send_cmd_and_read_resp(
- CMD_FMR_DP_BUFFER_SETSIZE, 1,
- parameters, &response_count, response_data);
- if (IOresult != FMD_RESULT_SUCCESS)
- err = IOresult;
+ io_result =
+ fmd_send_cmd_and_read_resp
+ (CMD_FMR_DP_BUFFER_SETSIZE, 1, parameters,
+ &response_count, response_data);
+ if (io_result != FMD_RESULT_SUCCESS)
+ err = io_result;
else
err = FMD_RESULT_SUCCESS;
}
- } else
+ } else {
err = FMD_RESULT_IO_ERROR;
- fmd_criticalsection_leave();
+ }
+
return err;
}
-uint8_t fmd_rx_buffer_set_threshold(
- void *context,
- uint8_t threshold
- )
+u8 fmd_rx_buffer_set_threshold(void *context, u8 threshold)
{
int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
- if (fmd_go_cmd_busy())
+ if (fmd_go_cmd_busy()) {
err = FMD_RESULT_BUSY;
- else if (g_fmd_initalized) {
- unsigned int IOresult;
- unsigned short parameters[1];
- unsigned int response_count;
- unsigned short response_data[8];
- if (threshold > 22)
+ } else if (fmd_state_info.fmd_initalized) {
+ u8 io_result;
+ u16 parameters[1];
+ u16 response_count;
+ u16 response_data[8];
+ if (threshold > MAX_RDS_GROUPS) {
err = FMD_RESULT_IO_ERROR;
- else {
+ } else {
parameters[0] = threshold;
- IOresult = fmd_send_cmd_and_read_resp(
- CMD_FMR_DP_BUFFER_SETTHRESHOLD, 1,
- parameters, &response_count, response_data);
- if (IOresult != FMD_RESULT_SUCCESS)
- err = IOresult;
+ io_result =
+ fmd_send_cmd_and_read_resp
+ (CMD_FMR_DP_BUFFER_SETTHRESHOLD, 1, parameters,
+ &response_count, response_data);
+ if (io_result != FMD_RESULT_SUCCESS)
+ err = io_result;
else
err = FMD_RESULT_SUCCESS;
}
- } else
+ } else {
err = FMD_RESULT_IO_ERROR;
- fmd_criticalsection_leave();
+ }
+
return err;
}
-uint8_t fmd_rx_set_ctrl(
- void *context,
- uint8_t onoffState
- )
+u8 fmd_rx_set_rds(void *context, u8 on_off_state)
{
int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
- if (fmd_go_cmd_busy())
+ if (fmd_go_cmd_busy()) {
err = FMD_RESULT_BUSY;
- else if (g_fmd_initalized) {
- unsigned int IOresult;
- unsigned short parameters[1];
- unsigned int response_count;
- unsigned short response_data[8];
-
- switch (onoffState) {
- case FMD_SWITCH_OFF_RDS_SIMULATOR:
+ } else if (fmd_state_info.fmd_initalized) {
+ u8 io_result;
+ u16 parameters[1];
+ u16 response_count;
+ u16 response_data[8];
+
+ switch (on_off_state) {
+ case FMD_SWITCH_ON_RDS_SIMULATOR:
parameters[0] = 0xFFFF;
break;
case FMD_SWITCH_OFF_RDS:
@@ -1971,44 +1913,42 @@ uint8_t fmd_rx_set_ctrl(
break;
}
- IOresult = fmd_send_cmd_and_read_resp(CMD_FMR_DP_SETCONTROL, 1,
- parameters, &response_count, response_data);
- if (IOresult != FMD_RESULT_SUCCESS)
- err = IOresult;
+ io_result = fmd_send_cmd_and_read_resp(CMD_FMR_DP_SETCONTROL, 1,
+ parameters,
+ &response_count,
+ response_data);
+ if (io_result != FMD_RESULT_SUCCESS)
+ err = io_result;
else
err = FMD_RESULT_SUCCESS;
- } else
+ } else {
err = FMD_RESULT_IO_ERROR;
- fmd_criticalsection_leave();
+ }
+
return err;
}
-uint8_t fmd_rx_get_low_level_rds_groups(
- void *context,
- uint8_t index,
- uint8_t *rds_buf_count,
- uint16_t *block1,
- uint16_t *block2,
- uint16_t *block3,
- uint16_t *block4,
- uint8_t *status1,
- uint8_t *status2,
- uint8_t *status3,
- uint8_t *status4
- )
+u8 fmd_rx_get_low_level_rds_groups(void *context,
+ u8 index,
+ u8 *rds_buf_count,
+ u16 *block1,
+ u16 *block2,
+ u16 *block3,
+ u16 *block4,
+ u8 *status1,
+ u8 *status2, u8 *status3, u8 *status4)
{
- struct fmd_state_info_s *state = (struct fmd_state_info_s *)context;
+ struct fmd_state_info_t *state = (struct fmd_state_info_t *)context;
int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
- if (fmd_go_cmd_busy())
+ if (fmd_go_cmd_busy()) {
err = FMD_RESULT_BUSY;
- else if (g_fmd_initalized) {
+ } else if (fmd_state_info.fmd_initalized) {
*rds_buf_count = state->rdsbufcnt;
- *block1 = state->rdsgroup[index].block[0];
- *block2 = state->rdsgroup[index].block[1];
- *block3 = state->rdsgroup[index].block[2];
- *block4 = state->rdsgroup[index].block[3];
+ *block1 = state->rdsgroup[index].block[0];
+ *block2 = state->rdsgroup[index].block[1];
+ *block3 = state->rdsgroup[index].block[2];
+ *block4 = state->rdsgroup[index].block[3];
*status1 = state->rdsgroup[index].status[0];
*status2 = state->rdsgroup[index].status[1];
*status3 = state->rdsgroup[index].status[2];
@@ -2016,539 +1956,881 @@ uint8_t fmd_rx_get_low_level_rds_groups(
err = FMD_RESULT_SUCCESS;
} else
err = FMD_RESULT_IO_ERROR;
- fmd_criticalsection_leave();
+
return err;
}
-uint8_t fmd_set_audio_dac(
- void *context,
- uint8_t dac_state
- )
+u8 fmd_tx_set_pa(void *context, bool on)
{
+ struct fmd_state_info_t *state = (struct fmd_state_info_t *)context;
int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
- if (fmd_go_cmd_busy())
+ if (fmd_go_cmd_busy()) {
err = FMD_RESULT_BUSY;
- else if (g_fmd_initalized) {
- unsigned int IOresult;
- unsigned short parameters[1];
- unsigned int response_count;
- unsigned short response_data[8];
-
- parameters[0] = dac_state;
-
- IOresult = fmd_send_cmd_and_read_resp(CMD_AUP_SETAUDIODAC, 1,
- parameters, &response_count, response_data);
- if (IOresult != FMD_RESULT_SUCCESS)
- err = IOresult;
+ } else if (fmd_state_info.fmd_initalized) {
+ u8 io_result;
+ u16 parameters[1];
+ u16 response_count;
+ u16 response_data[8];
+
+ if (on)
+ parameters[0] = 0x0001;
else
+ parameters[0] = 0x0000;
+
+ state->gocmd |= FMD_STATE_PA;
+ io_result = fmd_send_cmd_and_read_resp(CMD_FMT_PA_SETMODE, 1,
+ parameters,
+ &response_count,
+ response_data);
+ if (io_result != FMD_RESULT_SUCCESS) {
+ state->gocmd = FMD_STATE_NONE;
+ err = io_result;
+ } else {
+ os_get_cmd_sem();
err = FMD_RESULT_SUCCESS;
- } else
+ }
+ } else {
err = FMD_RESULT_IO_ERROR;
- fmd_criticalsection_leave();
+ }
+
return err;
}
-uint8_t fmd_set_balance(
- void *context,
- int8_t balance
- )
+u8 fmd_tx_set_signal_strength(void *context, u16 strength)
{
- struct fmd_state_info_s *state = (struct fmd_state_info_s *)context;
+ struct fmd_state_info_t *state = (struct fmd_state_info_t *)context;
int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
- if (fmd_go_cmd_busy())
+ if (fmd_go_cmd_busy()) {
+ err = FMD_RESULT_BUSY;
+ } else if (fmd_state_info.fmd_initalized) {
+ if ((strength >= MIN_POWER_LEVEL)
+ && (strength <= MAX_POWER_LEVEL)) {
+ u8 io_result;
+ u16 parameters[1];
+ u16 response_count;
+ u16 response_data[8];
+
+ parameters[0] = strength;
+
+ state->gocmd |= FMD_STATE_PA_LEVEL;
+ io_result =
+ fmd_send_cmd_and_read_resp(CMD_FMT_PA_SETCONTROL, 1,
+ parameters,
+ &response_count,
+ response_data);
+ if (io_result != FMD_RESULT_SUCCESS) {
+ state->gocmd = FMD_STATE_NONE;
+ err = io_result;
+ } else {
+ state->tx_strength = strength;
+ os_get_cmd_sem();
+ err = FMD_RESULT_SUCCESS;
+ }
+ } else {
+ err = FMD_RESULT_PARAMETER_INVALID;
+ }
+ } else {
+ err = FMD_RESULT_IO_ERROR;
+ }
+
+ return err;
+}
+
+u8 fmd_tx_get_signal_strength(void *context, u16 * strength)
+{
+ struct fmd_state_info_t *state = (struct fmd_state_info_t *)context;
+ int err = FMD_RESULT_FEATURE_UNSUPPORTED;
+
+ if (fmd_go_cmd_busy()) {
+ err = FMD_RESULT_BUSY;
+ } else if (fmd_state_info.fmd_initalized) {
+ *strength = state->tx_strength;
+ err = FMD_RESULT_SUCCESS;
+ } else {
+ err = FMD_RESULT_IO_ERROR;
+ }
+
+ return err;
+}
+
+u8 fmd_tx_set_freq_range(void *context, u8 range)
+{
+ struct fmd_state_info_t *state = (struct fmd_state_info_t *)context;
+ int err = FMD_RESULT_FEATURE_UNSUPPORTED;
+
+ if (fmd_go_cmd_busy()) {
err = FMD_RESULT_BUSY;
- else if (g_fmd_initalized) {
- unsigned int IOresult;
- unsigned short parameters[1];
- unsigned int response_count;
- unsigned short response_data[8];
- parameters[0] = (((signed short)balance)*0x7FFF) / 100;
- IOresult = fmd_send_cmd_and_read_resp(CMD_AUP_SETBALANCE, 1,
- parameters, &response_count, response_data);
- if (IOresult != FMD_RESULT_SUCCESS)
- err = IOresult;
- else {
- state->rx_balance = balance;
+ } else if (range > FMD_FREQRANGE_CHINA) {
+ err = FMD_RESULT_PARAMETER_INVALID;
+ } else if (fmd_state_info.fmd_initalized) {
+ u8 io_result;
+ u16 parameters[8];
+ u16 response_count;
+ u16 response_data[32];
+
+ parameters[0] = range;
+ parameters[1] = 0;
+ parameters[2] = 760;
+
+ io_result = fmd_send_cmd_and_read_resp(CMD_FMT_TN_SETBAND, 3,
+ parameters,
+ &response_count,
+ response_data);
+ if (io_result != FMD_RESULT_SUCCESS) {
+ err = io_result;
+ } else {
+ state->tx_freqrange = range;
err = FMD_RESULT_SUCCESS;
}
- } else
+ } else {
err = FMD_RESULT_IO_ERROR;
- fmd_criticalsection_leave();
+ }
+
return err;
}
-uint8_t fmd_get_balance(
- void *context,
- int8_t *balance
- )
+u8 fmd_tx_get_freq_range(void *context, u8 * range)
{
- struct fmd_state_info_s *state = (struct fmd_state_info_s *)context;
+ struct fmd_state_info_t *state = (struct fmd_state_info_t *)context;
int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
- if (fmd_go_cmd_busy())
+ if (fmd_go_cmd_busy()) {
err = FMD_RESULT_BUSY;
- else if (g_fmd_initalized) {
- *balance = state->rx_balance;
+ } else if (fmd_state_info.fmd_initalized) {
+ *range = state->tx_freqrange;
err = FMD_RESULT_SUCCESS;
- } else
+ } else {
err = FMD_RESULT_IO_ERROR;
- fmd_criticalsection_leave();
+ }
+
return err;
}
-uint8_t fmd_set_volume(
- void *context,
- uint8_t volume
- )
+u8 fmd_tx_set_grid(void *context, u8 grid)
{
- struct fmd_state_info_s *state = (struct fmd_state_info_s *)context;
int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
- if (fmd_go_cmd_busy())
+ if (fmd_go_cmd_busy()) {
err = FMD_RESULT_BUSY;
- else if (g_fmd_initalized) {
- unsigned int IOresult;
- unsigned short parameters[1];
- unsigned int response_count;
- unsigned short response_data[8];
-
- parameters[0] = (((unsigned short)volume)*0x7FFF) / 100;
-
- IOresult = fmd_send_cmd_and_read_resp(CMD_AUP_SETVOLUME, 1,
- parameters, &response_count, response_data);
- if (IOresult != FMD_RESULT_SUCCESS)
- err = IOresult;
- else {
- state->rx_volume = volume;
+ } else if (grid > FMD_GRID_200KHZ) {
+ err = FMD_RESULT_PARAMETER_INVALID;
+ } else if (fmd_state_info.fmd_initalized) {
+ u8 io_result;
+ u16 parameters[1];
+ u16 response_count;
+ u16 response_data[32];
+
+ parameters[0] = grid;
+
+ io_result = fmd_send_cmd_and_read_resp(CMD_FMT_TN_SETGRID, 1,
+ parameters,
+ &response_count,
+ response_data);
+ if (io_result != FMD_RESULT_SUCCESS)
+ err = io_result;
+ else
err = FMD_RESULT_SUCCESS;
+ } else {
+ err = FMD_RESULT_IO_ERROR;
+ }
+
+ return err;
+}
+
+u8 fmd_tx_set_preemphasis(void *context, u8 preemphasis)
+{
+ struct fmd_state_info_t *state = (struct fmd_state_info_t *)context;
+ int err = FMD_RESULT_FEATURE_UNSUPPORTED;
+
+ if (fmd_go_cmd_busy()) {
+ err = FMD_RESULT_BUSY;
+ } else if (fmd_state_info.fmd_initalized) {
+ u8 io_result;
+ u16 parameters[1];
+ u16 response_count;
+ u16 response_data[32];
+
+ switch (preemphasis) {
+ case FMD_EMPHASIS_50US:
+ parameters[0] = 1;
+ break;
+ case FMD_EMPHASIS_75US:
+ default:
+ parameters[0] = 2;
+ break;
}
- } else
+
+ io_result =
+ fmd_send_cmd_and_read_resp(CMD_FMT_RP_SETPREEMPHASIS, 1,
+ parameters, &response_count,
+ response_data);
+ if (io_result != FMD_RESULT_SUCCESS) {
+ err = io_result;
+ } else {
+ state->tx_preemphasis = preemphasis;
+ err = FMD_RESULT_SUCCESS;
+ }
+ } else {
err = FMD_RESULT_IO_ERROR;
- fmd_criticalsection_leave();
+ }
+
return err;
}
-uint8_t fmd_get_volume(
- void *context,
- uint8_t *volume
- )
+u8 fmd_tx_get_preemphasis(void *context, u8 * preemphasis)
{
- struct fmd_state_info_s *state = (struct fmd_state_info_s *)context;
+ struct fmd_state_info_t *state = (struct fmd_state_info_t *)context;
int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
- if (fmd_go_cmd_busy())
+ if (fmd_go_cmd_busy()) {
err = FMD_RESULT_BUSY;
- else if (g_fmd_initalized) {
- *volume = state->rx_volume;
+ } else if (fmd_state_info.fmd_initalized) {
+ *preemphasis = state->tx_preemphasis;
err = FMD_RESULT_SUCCESS;
- } else
+ } else {
err = FMD_RESULT_IO_ERROR;
- fmd_criticalsection_leave();
+ }
+
return err;
}
-uint8_t fmd_set_mute(
- void *context,
- bool mute_on
- )
+u8 fmd_tx_set_frequency(void *context, u32 freq)
{
- struct fmd_state_info_s *state = (struct fmd_state_info_s *)context;
+ struct fmd_state_info_t *state = (struct fmd_state_info_t *)context;
int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
- if (fmd_go_cmd_busy())
+ if (fmd_go_cmd_busy()) {
err = FMD_RESULT_BUSY;
- else if (g_fmd_initalized) {
- unsigned int IOresult;
- unsigned short parameters[2];
- unsigned int response_count;
- unsigned short response_data[8];
+ } else if (fmd_state_info.fmd_initalized) {
+ u8 io_result;
+ u16 parameters[8];
+ u16 response_count;
+ u16 response_data[8];
+
+ parameters[0] = fmd_tx_frequency_to_channel(context, freq);
+
+ state->gocmd |= FMD_STATE_FREQUENCY;
+ io_result =
+ fmd_send_cmd_and_read_resp(CMD_FMT_SP_TUNE_SETCHANNEL, 1,
+ parameters, &response_count,
+ response_data);
+ if (io_result != FMD_RESULT_SUCCESS) {
+ state->gocmd = FMD_STATE_NONE;
+ err = io_result;
+ } else {
+ os_get_cmd_sem();
+ err = FMD_RESULT_SUCCESS;
+ }
+ } else {
+ err = FMD_RESULT_IO_ERROR;
+ }
- state->rx_mute = mute_on;
- if (!mute_on)
- parameters[0] = 0x0000;
- else
- parameters[0] = 0x0001;
- parameters[1] = 0x0001;
+ return err;
+}
+
+u8 fmd_tx_get_frequency(void *context, u32 * freq)
+{
+ int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- IOresult = fmd_send_cmd_and_read_resp(CMD_AUP_SETMUTE, 2,
- parameters, &response_count, response_data);
- if (IOresult != FMD_RESULT_SUCCESS)
- err = IOresult;
- else {
- state->gocmd = fmd_gocmd_setmute;
- err = FMD_RESULT_WAIT;
+ if (fmd_go_cmd_busy()) {
+ err = FMD_RESULT_BUSY;
+ } else if (fmd_state_info.fmd_initalized) {
+ u8 io_result;
+ u16 response_count;
+ u16 response_data[8];
+
+ io_result =
+ fmd_send_cmd_and_read_resp(CMD_FMT_SP_TUNE_GETCHANNEL, 0,
+ NULL, &response_count,
+ response_data);
+ if (io_result != FMD_RESULT_SUCCESS) {
+ err = io_result;
+ } else {
+ *freq = fmd_tx_channel_to_frequency(context,
+ response_data[0]);
+ err = FMD_RESULT_SUCCESS;
}
- } else
+ } else {
+ err = FMD_RESULT_IO_ERROR;
+ }
+
+ return err;
+}
+
+u8 fmd_tx_enable_stereo_mode(void *context, bool enable_stereo_mode)
+{
+ struct fmd_state_info_t *state = (struct fmd_state_info_t *)context;
+ int err = FMD_RESULT_FEATURE_UNSUPPORTED;
+
+ if (fmd_go_cmd_busy()) {
+ err = FMD_RESULT_BUSY;
+ } else if (fmd_state_info.fmd_initalized) {
+ u8 io_result;
+ u16 parameters[8];
+ u16 response_count;
+ u16 response_data[8];
+
+ parameters[0] = enable_stereo_mode;
+
+ io_result =
+ fmd_send_cmd_and_read_resp(CMD_FMT_RP_STEREO_SETMODE, 1,
+ parameters, &response_count,
+ response_data);
+ if (io_result != FMD_RESULT_SUCCESS) {
+ err = io_result;
+ } else {
+ state->tx_stereomode = enable_stereo_mode;
+ err = FMD_RESULT_SUCCESS;
+ }
+
+ } else {
err = FMD_RESULT_IO_ERROR;
- fmd_criticalsection_leave();
+ }
+
return err;
}
-uint8_t fmd_get_mute(
- void *context,
- bool *mute_on
- )
+u8 fmd_tx_get_stereo_mode(void *context, bool * stereo_mode)
{
- struct fmd_state_info_s *state = (struct fmd_state_info_s *)context;
+ struct fmd_state_info_t *state = (struct fmd_state_info_t *)context;
int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
- if (fmd_go_cmd_busy())
+ if (fmd_go_cmd_busy()) {
err = FMD_RESULT_BUSY;
- else if (g_fmd_initalized) {
- *mute_on = state->rx_mute;
+ } else if (fmd_state_info.fmd_initalized) {
+ *stereo_mode = state->tx_stereomode;
err = FMD_RESULT_SUCCESS;
- } else
+ } else {
err = FMD_RESULT_IO_ERROR;
- fmd_criticalsection_leave();
+ }
+
return err;
}
-uint8_t fmd_bt_set_ctrl(
- void *context,
- bool up_conversion
- )
+u8 fmd_tx_set_pilot_deviation(void *context, u16 deviation)
{
+ struct fmd_state_info_t *state = (struct fmd_state_info_t *)context;
int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
- if (fmd_go_cmd_busy())
+ if (fmd_go_cmd_busy()) {
+ err = FMD_RESULT_BUSY;
+ } else if (fmd_state_info.fmd_initalized) {
+ if (deviation <= MAX_PILOT_DEVIATION) {
+ u8 io_result;
+ u16 parameters[1];
+ u16 response_count;
+ u16 response_data[8];
+ parameters[0] = deviation;
+
+ io_result =
+ fmd_send_cmd_and_read_resp
+ (CMD_FMT_RP_SETPILOTDEVIATION, 1, parameters,
+ &response_count, response_data);
+ if (io_result != FMD_RESULT_SUCCESS) {
+ err = io_result;
+ } else {
+ state->tx_pilotdev = deviation;
+ err = FMD_RESULT_SUCCESS;
+ }
+ } else {
+ err = FMD_RESULT_PARAMETER_INVALID;
+ }
+ } else {
+ err = FMD_RESULT_IO_ERROR;
+ }
+
+ return err;
+}
+
+u8 fmd_tx_get_pilot_deviation(void *context, u16 * deviation)
+{
+ struct fmd_state_info_t *state = (struct fmd_state_info_t *)context;
+ int err = FMD_RESULT_FEATURE_UNSUPPORTED;
+
+ if (fmd_go_cmd_busy()) {
+ err = FMD_RESULT_BUSY;
+ } else if (fmd_state_info.fmd_initalized) {
+ *deviation = state->tx_pilotdev;
+ err = FMD_RESULT_SUCCESS;
+ } else {
+ err = FMD_RESULT_IO_ERROR;
+ }
+
+ return err;
+}
+
+u8 fmd_tx_set_rds_deviation(void *context, u16 deviation)
+{
+ struct fmd_state_info_t *state = (struct fmd_state_info_t *)context;
+ int err = FMD_RESULT_FEATURE_UNSUPPORTED;
+
+ if (fmd_go_cmd_busy()) {
+ err = FMD_RESULT_BUSY;
+ } else if (fmd_state_info.fmd_initalized) {
+ if (deviation <= MAX_RDS_DEVIATION) {
+ u8 io_result;
+ u16 parameters[1];
+ u16 response_count;
+ u16 response_data[8];
+
+ parameters[0] = deviation;
+
+ io_result =
+ fmd_send_cmd_and_read_resp
+ (CMD_FMT_RP_SETRDSDEVIATION, 1, parameters,
+ &response_count, response_data);
+ if (io_result != FMD_RESULT_SUCCESS) {
+ err = io_result;
+ } else {
+ state->tx_rdsdev = deviation;
+ err = FMD_RESULT_SUCCESS;
+ }
+ } else {
+ err = FMD_RESULT_PARAMETER_INVALID;
+ }
+ } else {
+ err = FMD_RESULT_IO_ERROR;
+ }
+
+ return err;
+}
+
+u8 fmd_tx_get_rds_deviation(void *context, u16 * deviation)
+{
+ struct fmd_state_info_t *state = (struct fmd_state_info_t *)context;
+ int err = FMD_RESULT_FEATURE_UNSUPPORTED;
+
+ if (fmd_go_cmd_busy()) {
err = FMD_RESULT_BUSY;
- else if (g_fmd_initalized) {
- unsigned int IOresult;
- unsigned short parameters[1];
- unsigned int response_count;
- unsigned short response_data[8];
+ } else if (fmd_state_info.fmd_initalized) {
+ *deviation = state->tx_rdsdev;
+ err = FMD_RESULT_SUCCESS;
+ } else {
+ err = FMD_RESULT_IO_ERROR;
+ }
- if (up_conversion)
+ return err;
+}
+
+u8 fmd_tx_set_rds(void *context, bool on)
+{
+ struct fmd_state_info_t *state = (struct fmd_state_info_t *)context;
+ int err = FMD_RESULT_FEATURE_UNSUPPORTED;
+
+ if (fmd_go_cmd_busy()) {
+ err = FMD_RESULT_BUSY;
+ } else if (fmd_state_info.fmd_initalized) {
+ u8 io_result;
+ u16 parameters[1];
+ u16 response_count;
+ u16 response_data[8];
+
+ if (on)
+ parameters[0] = 0x0001;
+ else
parameters[0] = 0x0000;
+
+ io_result = fmd_send_cmd_and_read_resp(CMD_FMT_DP_SETCONTROL, 1,
+ parameters,
+ &response_count,
+ response_data);
+ if (io_result != FMD_RESULT_SUCCESS) {
+ err = io_result;
+ } else {
+ state->tx_rdson = on;
+ err = FMD_RESULT_SUCCESS;
+ }
+ } else {
+ err = FMD_RESULT_IO_ERROR;
+ }
+
+ return err;
+}
+
+u8 fmd_tx_set_group(void *context,
+ u16 position,
+ u8 block1[2], u8 block2[2], u8 block3[2], u8 block4[2]
+ )
+{
+ int err = FMD_RESULT_FEATURE_UNSUPPORTED;
+
+ if (fmd_go_cmd_busy()) {
+ err = FMD_RESULT_BUSY;
+ } else if (fmd_state_info.fmd_initalized) {
+ u8 io_result;
+ u16 parameters[5];
+ u16 response_count;
+ u16 response_data[8];
+
+ parameters[0] = position;
+ os_mem_copy(&parameters[1], block1, 2);
+ os_mem_copy(&parameters[2], block2, 2);
+ os_mem_copy(&parameters[3], block3, 2);
+ os_mem_copy(&parameters[4], block4, 2);
+
+ io_result =
+ fmd_send_cmd_and_read_resp(CMD_FMT_DP_BUFFER_SETGROUP, 5,
+ parameters, &response_count,
+ response_data);
+ if (io_result != FMD_RESULT_SUCCESS)
+ err = io_result;
else
- parameters[0] = 0x0001;
+ err = FMD_RESULT_SUCCESS;
+ } else {
+ err = FMD_RESULT_IO_ERROR;
+ }
- IOresult = fmd_send_cmd_and_read_resp(CMD_AUP_BT_SETCONTROL, 1,
- parameters, &response_count, response_data);
- if (IOresult != FMD_RESULT_SUCCESS)
- err = IOresult;
+ return err;
+}
+
+u8 fmd_tx_buffer_set_size(void *context, u16 buffer_size)
+{
+ int err = FMD_RESULT_FEATURE_UNSUPPORTED;
+
+ if (fmd_go_cmd_busy()) {
+ err = FMD_RESULT_BUSY;
+ } else if (fmd_state_info.fmd_initalized) {
+ u8 io_result;
+ u16 parameters[1];
+ u16 response_count;
+ u16 response_data[8];
+ parameters[0] = buffer_size;
+ io_result =
+ fmd_send_cmd_and_read_resp(CMD_FMT_DP_BUFFER_SETSIZE, 1,
+ parameters, &response_count,
+ response_data);
+ if (io_result != FMD_RESULT_SUCCESS)
+ err = io_result;
else
err = FMD_RESULT_SUCCESS;
- } else
+ } else {
err = FMD_RESULT_IO_ERROR;
- fmd_criticalsection_leave();
+ }
+
return err;
+
}
-uint8_t fmd_bt_set_mode(
- void *context,
- uint8_t output
- )
+u8 fmd_tx_get_rds(void *context, bool * on)
{
+ struct fmd_state_info_t *state = (struct fmd_state_info_t *)context;
int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
- if (fmd_go_cmd_busy())
+ if (fmd_go_cmd_busy()) {
err = FMD_RESULT_BUSY;
- else if (g_fmd_initalized) {
- unsigned int IOresult;
- unsigned short parameters[1];
- unsigned int response_count;
- unsigned short response_data[8];
-
- switch (output) {
- case FMD_OUTPUT_DISABLED:
- default:
- parameters[0] = 0x0000;
- break;
- case FMD_OUTPUT_I2S:
- parameters[0] = 0x0001;
- break;
- case FMD_OUTPUT_PARALLEL:
- parameters[0] = 0x0002;
- break;
- case FMD_OUTPUT_FIFO:
- parameters[0] = 0x0003;
- break;
- }
+ } else if (fmd_state_info.fmd_initalized) {
+ *on = state->tx_rdson;
+ err = FMD_RESULT_SUCCESS;
+ } else {
+ err = FMD_RESULT_IO_ERROR;
+ }
- IOresult = fmd_send_cmd_and_read_resp(CMD_AUP_BT_SETMODE, 1,
- parameters, &response_count, response_data);
- if (IOresult != FMD_RESULT_SUCCESS)
- err = IOresult;
+ return err;
+}
+
+u8 fmd_set_balance(void *context, s8 balance)
+{
+ int err = FMD_RESULT_FEATURE_UNSUPPORTED;
+
+ if (fmd_go_cmd_busy()) {
+ err = FMD_RESULT_BUSY;
+ } else if (fmd_state_info.fmd_initalized) {
+ u8 io_result;
+ u16 parameters[1];
+ u16 response_count;
+ u16 response_data[8];
+ parameters[0] = (((signed short)balance) * 0x7FFF) / 100;
+ io_result = fmd_send_cmd_and_read_resp(CMD_AUP_SETBALANCE, 1,
+ parameters,
+ &response_count,
+ response_data);
+ if (io_result != FMD_RESULT_SUCCESS)
+ err = io_result;
else
err = FMD_RESULT_SUCCESS;
- } else
+ } else {
err = FMD_RESULT_IO_ERROR;
- fmd_criticalsection_leave();
+ }
+
return err;
}
-uint8_t fmd_ext_set_mode(
- void *context,
- uint8_t output
- )
+u8 fmd_set_volume(void *context, u8 volume)
{
+ struct fmd_state_info_t *state = (struct fmd_state_info_t *)context;
int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
- if (fmd_go_cmd_busy())
+ if (fmd_go_cmd_busy()) {
err = FMD_RESULT_BUSY;
- else if (g_fmd_initalized) {
- unsigned int IOresult;
- unsigned short parameters[1];
- unsigned int response_count;
- unsigned short response_data[8];
-
- switch (output) {
- case FMD_OUTPUT_DISABLED:
- default:
- parameters[0] = 0x0000;
- break;
- case FMD_OUTPUT_I2S:
- parameters[0] = 0x0001;
- break;
- case FMD_OUTPUT_PARALLEL:
- parameters[0] = 0x0002;
- break;
+ } else if (fmd_state_info.fmd_initalized) {
+ u8 io_result;
+ u16 parameters[1];
+ u16 response_count;
+ u16 response_data[8];
+
+ parameters[0] = (((u16) volume) * 0x7FFF) / 100;
+
+ io_result = fmd_send_cmd_and_read_resp(CMD_AUP_SETVOLUME, 1,
+ parameters,
+ &response_count,
+ response_data);
+ if (io_result != FMD_RESULT_SUCCESS) {
+ err = io_result;
+ } else {
+ state->rx_volume = volume;
+ err = FMD_RESULT_SUCCESS;
}
+ } else {
+ err = FMD_RESULT_IO_ERROR;
+ }
- IOresult = fmd_send_cmd_and_read_resp(CMD_AUP_EXT_SETMODE, 1,
- parameters, &response_count, response_data);
- if (IOresult != FMD_RESULT_SUCCESS)
- err = IOresult;
- else
- err = FMD_RESULT_SUCCESS;
- } else
+ return err;
+}
+
+u8 fmd_get_volume(void *context, u8 * volume)
+{
+ struct fmd_state_info_t *state = (struct fmd_state_info_t *)context;
+ int err = FMD_RESULT_FEATURE_UNSUPPORTED;
+
+ if (fmd_go_cmd_busy()) {
+ err = FMD_RESULT_BUSY;
+ } else if (fmd_state_info.fmd_initalized) {
+ *volume = state->rx_volume;
+ err = FMD_RESULT_SUCCESS;
+ } else {
err = FMD_RESULT_IO_ERROR;
- fmd_criticalsection_leave();
+ }
+
return err;
}
-uint8_t fmd_ext_set_ctrl(
- void *context,
- bool up_conversion
- )
+u8 fmd_set_mute(void *context, bool mute_on)
{
+ struct fmd_state_info_t *state = (struct fmd_state_info_t *)context;
int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
- if (fmd_go_cmd_busy())
+ if (fmd_go_cmd_busy()) {
err = FMD_RESULT_BUSY;
- else if (g_fmd_initalized) {
- unsigned int IOresult;
- unsigned short parameters[1];
- unsigned int response_count;
- unsigned short response_data[8];
+ } else if (fmd_state_info.fmd_initalized) {
+ u8 io_result;
+ u16 parameters[2];
+ u16 response_count;
+ u16 response_data[8];
- if (up_conversion)
+ if (!mute_on)
parameters[0] = 0x0000;
else
parameters[0] = 0x0001;
+ parameters[1] = 0x0001;
- IOresult = fmd_send_cmd_and_read_resp(CMD_AUP_EXT_SETCONTROL, 1,
- parameters, &response_count, response_data);
- if (IOresult != FMD_RESULT_SUCCESS)
- err = IOresult;
- else
+ state->gocmd |= FMD_STATE_MUTE;
+ io_result = fmd_send_cmd_and_read_resp(CMD_AUP_SETMUTE, 2,
+ parameters,
+ &response_count,
+ response_data);
+ if (io_result != FMD_RESULT_SUCCESS) {
+ state->gocmd = FMD_STATE_NONE;
+ err = io_result;
+ } else {
+ os_get_cmd_sem();
err = FMD_RESULT_SUCCESS;
- } else
+ }
+ } else {
err = FMD_RESULT_IO_ERROR;
- fmd_criticalsection_leave();
+ }
+
return err;
}
-uint8_t fmd_ext_set_mute(
- void *context,
- bool mute_on
- )
+u8 fmd_ext_set_mute(void *context, bool mute_on)
{
- struct fmd_state_info_s *state = (struct fmd_state_info_s *)context;
int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
- if (fmd_go_cmd_busy())
+ if (fmd_go_cmd_busy()) {
err = FMD_RESULT_BUSY;
- else if (g_fmd_initalized) {
- unsigned int IOresult;
- unsigned short parameters[2];
- unsigned int response_count;
- unsigned short response_data[8];
+ } else if (fmd_state_info.fmd_initalized) {
+ u8 io_result;
+ u16 parameters[2];
+ u16 response_count;
+ u16 response_data[8];
- state->rx_mute = mute_on;
if (!mute_on)
parameters[0] = 0x0000;
else
parameters[0] = 0x0001;
- IOresult = fmd_send_cmd_and_read_resp(CMD_AUP_EXT_SETMUTE, 1,
- parameters, &response_count, response_data);
- if (IOresult != FMD_RESULT_SUCCESS)
- err = IOresult;
+ io_result = fmd_send_cmd_and_read_resp(CMD_AUP_EXT_SETMUTE, 1,
+ parameters,
+ &response_count,
+ response_data);
+ if (io_result != FMD_RESULT_SUCCESS)
+ err = io_result;
else
err = FMD_RESULT_SUCCESS;
- } else
+ } else {
err = FMD_RESULT_IO_ERROR;
- fmd_criticalsection_leave();
+ }
+
return err;
}
-uint8_t fmd_power_up(
- void *context
- )
+u8 fmd_power_up(void *context)
{
- struct fmd_state_info_s *state = (struct fmd_state_info_s *)context;
+ struct fmd_state_info_t *state = (struct fmd_state_info_t *)context;
int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
-
- if (g_fmd_initalized) {
- unsigned int IOresult;
- unsigned int response_count;
- unsigned short response_data[8];
-
- IOresult = fmd_send_cmd_and_read_resp(CMD_GEN_POWERUP, 0,
- NULL, &response_count, response_data);
- if (IOresult != FMD_RESULT_SUCCESS) {
- err = IOresult;
+ if (fmd_state_info.fmd_initalized) {
+ u8 io_result;
+ u16 response_count;
+ u16 response_data[8];
+
+ state->gocmd |= FMD_STATE_GEN_POWERUP;
+ io_result = fmd_send_cmd_and_read_resp(CMD_GEN_POWERUP, 0,
+ NULL, &response_count,
+ response_data);
+ if (io_result != FMD_RESULT_SUCCESS) {
+ state->gocmd = FMD_STATE_NONE;
+ err = io_result;
} else {
- state->gocmd = fmd_gocmd_genpowerup;
- err = FMD_RESULT_WAIT;
+ os_get_cmd_sem();
+ err = FMD_RESULT_SUCCESS;
}
- } else
+ } else {
err = FMD_RESULT_IO_ERROR;
- fmd_criticalsection_leave();
+ }
+
return err;
}
-uint8_t fmd_goto_standby(
- void *context
- )
+u8 fmd_goto_standby(void *context)
{
int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
- if (g_fmd_initalized) {
- unsigned int IOresult;
- unsigned int response_count;
- unsigned short response_data[8];
+ if (fmd_state_info.fmd_initalized) {
+ u8 io_result;
+ u16 response_count;
+ u16 response_data[8];
- IOresult = fmd_send_cmd_and_read_resp(CMD_GEN_GOTOSTANDBY, 0,
- NULL, &response_count, response_data);
- if (IOresult != FMD_RESULT_SUCCESS)
- err = IOresult;
+ io_result = fmd_send_cmd_and_read_resp(CMD_GEN_GOTOSTANDBY, 0,
+ NULL, &response_count,
+ response_data);
+ if (io_result != FMD_RESULT_SUCCESS)
+ err = io_result;
else
err = FMD_RESULT_SUCCESS;
- } else
+ } else {
err = FMD_RESULT_IO_ERROR;
- fmd_criticalsection_leave();
+ }
+
return err;
}
-uint8_t fmd_goto_power_down(
- void *context
- )
+u8 fmd_goto_power_down(void *context)
{
int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
- if (g_fmd_initalized) {
- unsigned int IOresult;
- unsigned int response_count;
- unsigned short response_data[8];
+ if (fmd_state_info.fmd_initalized) {
+ u8 io_result;
+ u16 response_count;
+ u16 response_data[8];
- IOresult = fmd_send_cmd_and_read_resp(CMD_GEN_GOTOPOWERDOWN, 0,
- NULL, &response_count, response_data);
- if (IOresult != FMD_RESULT_SUCCESS)
- err = IOresult;
+ io_result = fmd_send_cmd_and_read_resp(CMD_GEN_GOTOPOWERDOWN, 0,
+ NULL, &response_count,
+ response_data);
+ if (io_result != FMD_RESULT_SUCCESS)
+ err = io_result;
else
err = FMD_RESULT_SUCCESS;
- } else
+ } else {
err = FMD_RESULT_IO_ERROR;
- fmd_criticalsection_leave();
+ }
+
return err;
}
-uint8_t fmd_select_ref_clk(
- void *context,
- uint16_t ref_clk
- )
+u8 fmd_select_ref_clk(void *context, u16 ref_clk)
{
+ struct fmd_state_info_t *state = (struct fmd_state_info_t *)context;
int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
- if (fmd_go_cmd_busy())
+ if (fmd_go_cmd_busy()) {
err = FMD_RESULT_BUSY;
- else if (g_fmd_initalized) {
- unsigned int IOresult;
- unsigned short parameters[1];
- unsigned int response_count;
- unsigned short response_data[8];
+ } else if (fmd_state_info.fmd_initalized) {
+ u8 io_result;
+ u16 parameters[1];
+ u16 response_count;
+ u16 response_data[8];
parameters[0] = ref_clk;
- IOresult = fmd_send_cmd_and_read_resp(
- CMD_GEN_SELECTREFERENCECLOCK,
- 1, parameters, &response_count, response_data);
- if (IOresult != FMD_RESULT_SUCCESS)
- err = IOresult;
- else
+ state->gocmd |= FMD_STATE_SELECT_REF_CLK;
+ io_result =
+ fmd_send_cmd_and_read_resp(CMD_GEN_SELECTREFERENCECLOCK, 1,
+ parameters, &response_count,
+ response_data);
+ if (io_result != FMD_RESULT_SUCCESS) {
+ state->gocmd = FMD_STATE_NONE;
+ err = io_result;
+ } else {
+ os_get_cmd_sem();
err = FMD_RESULT_SUCCESS;
- } else
+ }
+ } else {
err = FMD_RESULT_IO_ERROR;
- fmd_criticalsection_leave();
+ }
+
return err;
}
-uint8_t fmd_select_ref_clk_pll(
- void *context,
- uint16_t freq
- )
+u8 fmd_set_ref_clk_pll(void *context, u16 freq)
{
+ struct fmd_state_info_t *state = (struct fmd_state_info_t *)context;
int err = FMD_RESULT_FEATURE_UNSUPPORTED;
- fmd_criticalsection_enter();
- if (fmd_go_cmd_busy())
+ if (fmd_go_cmd_busy()) {
err = FMD_RESULT_BUSY;
- else if (g_fmd_initalized) {
- unsigned int IOresult;
- unsigned short parameters[1];
- unsigned int response_count;
- unsigned short response_data[8];
+ } else if (fmd_state_info.fmd_initalized) {
+ u8 io_result;
+ u16 parameters[1];
+ u16 response_count;
+ u16 response_data[8];
parameters[0] = freq;
- IOresult = fmd_send_cmd_and_read_resp(
- CMD_GEN_SETREFERENCECLOCKPLL,
- 1, parameters, &response_count, response_data);
- if (IOresult != FMD_RESULT_SUCCESS)
- err = IOresult;
- else
+ state->gocmd |= FMD_STATE_SET_REF_CLK_PLL;
+ io_result =
+ fmd_send_cmd_and_read_resp(CMD_GEN_SETREFERENCECLOCKPLL, 1,
+ parameters, &response_count,
+ response_data);
+ if (io_result != FMD_RESULT_SUCCESS) {
+ state->gocmd = FMD_STATE_NONE;
+ err = io_result;
+ } else {
+ os_get_cmd_sem();
err = FMD_RESULT_SUCCESS;
- } else
+ }
+ } else {
err = FMD_RESULT_IO_ERROR;
- fmd_criticalsection_leave();
+ }
+
return err;
}
-unsigned int fmd_send_fm_ip_enable(void)
+u8 fmd_send_fm_ip_enable(void)
{
- uint8_t FMIP_EnableCmd[5];
- unsigned int err = 0;
+ u8 FMIP_EnableCmd[5];
+ u8 err = 0;
FMIP_EnableCmd[0] = HCI_PACKET_INDICATOR_FM_CMD_EVT;
- FMIP_EnableCmd[1] = 0x03 ; /* Length of following Bytes */
+ FMIP_EnableCmd[1] = 0x03; /* Length of following Bytes */
FMIP_EnableCmd[2] = CATENA_OPCODE;
- FMIP_EnableCmd[3] = FM_WRITE ;
+ FMIP_EnableCmd[3] = FM_WRITE;
FMIP_EnableCmd[4] = FM_FUNCTION_ENABLE;
/* Send the Packet */
- err = ste_fm_send_packet(5 , FMIP_EnableCmd);
+ err = ste_fm_send_packet(5, FMIP_EnableCmd);
/* wait till response comes */
os_get_cmd_sem();
@@ -2556,19 +2838,19 @@ unsigned int fmd_send_fm_ip_enable(void)
return err;
}
-unsigned int fmd_send_fm_ip_disable(void)
+u8 fmd_send_fm_ip_disable(void)
{
- uint8_t FMIP_DisableCmd[5];
- unsigned int err = 0;
+ u8 FMIP_DisableCmd[5];
+ u8 err = 0;
FMIP_DisableCmd[0] = HCI_PACKET_INDICATOR_FM_CMD_EVT;
- FMIP_DisableCmd[1] = 0x03 ; /* Length of following Bytes */
+ FMIP_DisableCmd[1] = 0x03; /* Length of following Bytes */
FMIP_DisableCmd[2] = CATENA_OPCODE;
- FMIP_DisableCmd[3] = FM_WRITE ;
+ FMIP_DisableCmd[3] = FM_WRITE;
FMIP_DisableCmd[4] = FM_FUNCTION_DISABLE;
/* Send the Packet */
- err = ste_fm_send_packet(5 , FMIP_DisableCmd);
+ err = ste_fm_send_packet(5, FMIP_DisableCmd);
/* wait till response comes */
os_get_cmd_sem();
@@ -2576,36 +2858,13 @@ unsigned int fmd_send_fm_ip_disable(void)
return err;
}
-unsigned int fmd_send_fm_ip_reset(void)
+u8 fmd_send_fm_firmware(u8 *fw_buffer, u16 fw_size)
{
- uint8_t FMIP_ResetCmd[5];
- unsigned int err = 0;
-
- FMIP_ResetCmd[0] = HCI_PACKET_INDICATOR_FM_CMD_EVT;
- FMIP_ResetCmd[1] = 0x03 ; /* Length of following Bytes */
- FMIP_ResetCmd[2] = CATENA_OPCODE;
- FMIP_ResetCmd[3] = FM_WRITE ;
- FMIP_ResetCmd[4] = FM_FUNCTION_RESET;
-
- /* Send the Packet */
- err = ste_fm_send_packet(5 , FMIP_ResetCmd);
-
- /* wait till response comes */
- os_get_cmd_sem();
-
- return err;
-}
-
-unsigned int fmd_send_fm_firmware(
- uint8_t *fw_buffer,
- uint16_t fw_size
- )
-{
- unsigned int err = 0;
- uint16_t bytes_to_write = ST_WRITE_FILE_BLK_SIZE - 4;
- uint16_t bytes_remaining = fw_size;
- uint8_t fm_firmware_data[ST_WRITE_FILE_BLK_SIZE + 6];
- uint32_t block_id = 0;
+ u8 err = 0;
+ u16 bytes_to_write = ST_WRITE_FILE_BLK_SIZE - 4;
+ u16 bytes_remaining = fw_size;
+ u8 fm_firmware_data[ST_WRITE_FILE_BLK_SIZE + 6];
+ u32 block_id = 0;
while (bytes_remaining > 0) {
if (bytes_remaining < ST_WRITE_FILE_BLK_SIZE - 4)
@@ -2615,8 +2874,8 @@ unsigned int fmd_send_fm_firmware(
* so shift the firmware data by 6 bytes
*/
os_mem_copy(fm_firmware_data + 6, fw_buffer, bytes_to_write);
- err = fmd_st_write_file_block(block_id , fm_firmware_data ,
- bytes_to_write);
+ err = fmd_write_file_block(block_id, fm_firmware_data,
+ bytes_to_write);
if (!err) {
block_id++;
fw_buffer += bytes_to_write;
@@ -2625,84 +2884,106 @@ unsigned int fmd_send_fm_firmware(
if (block_id == 256)
block_id = 0;
} else {
- FM_DEBUG_REPORT("fmd_send_fm_firmware: "\
- "Failed to download %d"\
- "Block, error = %d",
- (unsigned int)block_id, err);
- return err;
+ FM_DEBUG_REPORT("fmd_send_fm_firmware: "
+ "Failed to download %d"
+ "Block, error = %d",
+ (unsigned int)block_id, err);
+ return err;
}
}
return err;
}
-void fmd_receive_data(
- uint32_t packet_length,
- uint8_t *packet_buffer
- )
+void fmd_receive_data(u16 packet_length, u8 *packet_buffer)
{
if (packet_buffer != NULL) {
- if (packet_length == 0) {
- uint32_t interrupt;
- interrupt = ((uint32_t) *(packet_buffer + 1) << 8) |
- ((uint32_t) *packet_buffer) ;
+ if (packet_length == 0x04 &&
+ packet_buffer[0] == CATENA_OPCODE &&
+ packet_buffer[1] == FM_EVENT) {
+ /* PG 1.0 interrupt Handling */
+ u16 interrupt;
+ interrupt = (u16) (packet_buffer[3] << 8) |
+ (u16) packet_buffer[2];
FM_DEBUG_REPORT("interrupt = %04x",
- (unsigned int)interrupt);
- fmd_interrupt_handler(interrupt);
- } else {
- switch (packet_buffer[0]) {
+ (unsigned int)interrupt);
+ fmd_add_interrupt_to_queue(interrupt);
+ } else if (packet_length == 0x06 &&
+ packet_buffer[0] == 0x00 &&
+ packet_buffer[1] == CATENA_OPCODE &&
+ packet_buffer[2] == 0x01 &&
+ packet_buffer[3] == FM_EVENT) {
+ /* PG 2.0 interrupt Handling */
+ u16 interrupt;
+ interrupt = (u16) (packet_buffer[5] << 8) |
+ (u16) packet_buffer[4];
+ FM_DEBUG_REPORT("interrupt = %04x",
+ (unsigned int)interrupt);
+ fmd_add_interrupt_to_queue(interrupt);
+ } else if (packet_buffer[0] == 0x00 &&
+ packet_buffer[1] == CATENA_OPCODE &&
+ packet_buffer[2] == FM_WRITE) {
+ /* Command Complete or RDS Data Handling */
+ switch (packet_buffer[3]) {
case FM_CMD_STATUS_CMD_SUCCESS:
- {
- fmd_process_fm_function(packet_buffer+1);
- }
- break;
+ {
+ fmd_process_fm_function(&packet_buffer
+ [4]);
+ }
+ break;
case FM_CMD_STATUS_HCI_ERR_HW_FAILURE:
- {
- FM_DEBUG_REPORT(
- "FM_CMD_STATUS_HCI_ERR_HW_FAILURE");
- }
- break;
+ {
+ FM_DEBUG_REPORT
+ ("FM_CMD_STATUS_HCI_ERR_HW_FAILURE"
+ );
+ }
+ break;
case FM_CMD_STATUS_HCI_ERR_INVALID_PARAMETERS:
- {
- FM_DEBUG_REPORT(
- "FM_CMD_STATUS_HCI_ERR_INVALID_PARAMETERS");
- }
- break;
+ {
+ FM_DEBUG_REPORT
+ ("FM_CMD_STATUS_HCI_ERR_INVALID_"
+ "PARAMETERS");
+ }
+ break;
case FM_CMD_STATUS_IP_UNINIT:
- {
- FM_DEBUG_REPORT("FM_CMD_STATUS_IP_UNINIT");
- }
- break;
+ {
+ FM_DEBUG_REPORT
+ ("FM_CMD_STATUS_IP_UNINIT");
+ }
+ break;
case FM_CMD_STATUS_HCI_ERR_UNSPECIFIED_ERROR:
- {
- FM_DEBUG_REPORT(
- "FM_CMD_STATUS_HCI_ERR_UNSPECIFIED_ERROR");
- }
- break;
+ {
+ FM_DEBUG_REPORT
+ ("FM_CMD_STATUS_HCI_ERR_UNSPECIFIED"
+ "_ERROR");
+ }
+ break;
case FM_CMD_STATUS_HCI_ERR_CMD_DISALLOWED:
- {
- FM_DEBUG_REPORT(
- "FM_CMD_STATUS_HCI_ERR_CMD_DISALLOWED");
- }
- break;
+ {
+ FM_DEBUG_REPORT
+ ("FM_CMD_STATUS_HCI_ERR_CMD_"
+ "DISALLOWED");
+ }
+ break;
case FM_CMD_STATUS_WRONG_SEQ_NUM:
- {
- FM_DEBUG_REPORT(
- "FM_CMD_STATUS_WRONG_SEQ_NUM");
- }
- break;
+ {
+ FM_DEBUG_REPORT
+ ("FM_CMD_STATUS_WRONG_SEQ_NUM");
+ }
+ break;
case FM_CMD_STATUS_UNKOWNFILE_TYPE:
- {
- FM_DEBUG_REPORT(
- "FM_CMD_STATUS_UNKOWNFILE_TYPE");
- }
- break;
+ {
+ FM_DEBUG_REPORT
+ ("FM_CMD_STATUS_UNKOWNFILE_TYPE");
+ }
+ break;
case FM_CMD_STATUS_FILE_VERSION_MISMATCH:
- {
- FM_DEBUG_REPORT(
- "FM_CMD_STATUS_FILE_VERSION_MISMATCH");
- }
- break;
+ {
+ FM_DEBUG_REPORT
+ ("FM_CMD_STATUS_FILE_VERSION_"
+ "MISMATCH");
+ }
+ break;
}
}
} else {
@@ -2712,48 +2993,44 @@ void fmd_receive_data(
void fmd_int_bufferfull(void)
{
- unsigned int response_count;
- unsigned short response_data[16];
- unsigned short cnt;
- unsigned short index = 0;
- unsigned int IOresult;
- struct fmd_rdsgroup_s rdsgroup;
+ u16 response_count;
+ u16 response_data[16];
+ u16 cnt;
+ u16 index = 0;
+ u8 io_result;
+ struct fmd_rdsgroup_t rdsgroup;
if (fmd_state_info.rx_rdson) {
- /* get group count*/
- IOresult = fmd_send_cmd_and_read_resp(
- CMD_FMR_DP_BUFFER_GETGROUPCOUNT, 0, NULL,
- &response_count, response_data);
- if (IOresult == FMD_RESULT_SUCCESS) {
+ /* get group count */
+ io_result =
+ fmd_send_cmd_and_read_resp(CMD_FMR_DP_BUFFER_GETGROUPCOUNT,
+ 0, NULL, &response_count,
+ response_data);
+ if (io_result == FMD_RESULT_SUCCESS) {
/* read RDS groups */
cnt = response_data[0];
- if (cnt > MAX_RDS_GROUPS_READ)
- cnt = MAX_RDS_GROUPS_READ;
+ if (cnt > MAX_RDS_GROUPS)
+ cnt = MAX_RDS_GROUPS;
fmd_state_info.rdsbufcnt = cnt;
while (cnt-- && fmd_state_info.rx_rdson) {
- IOresult = fmd_send_cmd_and_read_resp(
- CMD_FMR_DP_BUFFER_GETGROUP, 0, NULL,
- &response_count,
- (unsigned short *)&rdsgroup);
- if (IOresult == FMD_RESULT_SUCCESS) {
+ io_result =
+ fmd_send_cmd_and_read_resp
+ (CMD_FMR_DP_BUFFER_GETGROUP, 0, NULL,
+ &response_count, (u16 *) &rdsgroup);
+ if (io_result == FMD_RESULT_SUCCESS)
if (fmd_state_info.rx_rdson)
fmd_state_info.rdsgroup[index++]
- = rdsgroup;
- }
+ = rdsgroup;
}
}
}
}
-void fmd_hexdump(
- char prompt,
- uint8_t *arr,
- int num_bytes
- )
+void fmd_hexdump(char prompt, u8 *arr, int num_bytes)
{
int i;
- uint8_t tmpVal;
- static unsigned char pkt_write[512], *pkt_ptr;
+ u8 tmpVal;
+ static u8 pkt_write[512], *pkt_ptr;
sprintf(pkt_write, "\n[%04x] %c", num_bytes, prompt);
pkt_ptr = pkt_write + strlen(pkt_write);
if (arr != NULL) {
@@ -2776,4 +3053,3 @@ void fmd_hexdump(
MODULE_AUTHOR("Hemant Gupta");
MODULE_LICENSE("GPL v2");
-
diff --git a/drivers/media/radio/CG2900/fmdriver.h b/drivers/media/radio/CG2900/fmdriver.h
index ad3e804df1d..28ab6c649e4 100755
--- a/drivers/media/radio/CG2900/fmdriver.h
+++ b/drivers/media/radio/CG2900/fmdriver.h
@@ -1,6 +1,4 @@
/*
- * file fmdriver.h
- *
* Copyright (C) ST-Ericsson SA 2010
*
* Linux FM Driver for CG2900 FM Chip
@@ -13,85 +11,83 @@
#ifndef _FMDRIVER_H_
#define _FMDRIVER_H_
-#define IRPT_OPERATIONSUCCEEDED 0
-#define IRPT_OPERATIONFAILED 1
-#define IRPT_BUFFERFULL 3
-#define IRPT_SIGNALQUALITYLOW 4
-#define IRPT_MONOSTEREOTRANSITION 5
-#define IRPT_RDSSYNCFOUND 6
-#define IRPT_RDSSYNCLOST 7
-#define IRPT_PICODECHANGED 8
-#define IRPT_REQUESTEDBLOCKAVAILABLE 9
-#define IRPT_BUFFER_CLEARED 13
-#define IRPT_WARMBOOTREADY 14
-#define IRPT_COLDBOOTREADY 15
-#define IRPT_BUFFEREMPTY 3
-#define IRPT_MUTESTATUSCHANGED 4
-#define IRPT_OVERMODULATION 5
-#define IRPT_INPUTOVERDRIVE 6
-
-#define CMD_AIP_BT_SETCONTROL 0x01A6
-#define CMD_AIP_BT_SETMODE 0x01E6
-#define CMD_AIP_FADE_START 0x0046
-#define CMD_AIP_LEVEL_GETSTATUS 0x0106
-#define CMD_AIP_LEVEL_SETMODE 0x00E6
-#define CMD_AIP_OVERDRIVE_SETCONTROL 0x0166
-#define CMD_AIP_OVERDRIVE_SETMODE 0x0126
-#define CMD_AIP_SETAUDIOADC 0x00A6
-#define CMD_AIP_SETAUDIOADC_CONTROL 0x00C6
-#define CMD_AIP_SETBALANCE 0x0086
-#define CMD_AIP_SETGAIN 0x0066
-#define CMD_AIP_SETMIXER 0x0146
-#define CMD_AIP_SETMODE 0x01C6
-#define CMD_AUP_BT_SETBALANCE 0x0142
-#define CMD_AUP_BT_SETCONTROL 0x00E2
-#define CMD_AUP_BT_SETMODE 0x00C2
-#define CMD_AUP_BT_SETVOLUME 0x0122
-#define CMD_AUP_EXT_SETCONTROL 0x0182
-#define CMD_AUP_EXT_SETMODE 0x0162
-#define CMD_AUP_EXT_FADESTART 0x0102
-#define CMD_AUP_EXT_SETMUTE 0x01E2
-#define CMD_AUP_FADE_START 0x00A2
-#define CMD_AUP_SETAUDIODAC 0x0082
-#define CMD_AUP_SETBALANCE 0x0042
-#define CMD_AUP_SETMUTE 0x0062
-#define CMD_AUP_SETVOLUME 0x0022
-#define CMD_FMR_DP_BLOCKREQUEST_CONTROL 0x0583
-#define CMD_FMR_DP_BLOCKREQUEST_GETBLOCK 0x05A3
-#define CMD_FMR_DP_BUFFER_GETGROUP 0x0303
-#define CMD_FMR_DP_BUFFER_GETGROUPCOUNT 0x0323
-#define CMD_FMR_DP_BUFFER_SETSIZE 0x0343
-#define CMD_FMR_DP_BUFFER_SETTHRESHOLD 0x06C3
-#define CMD_FMR_DP_GETSTATE 0x0283
-#define CMD_FMR_DP_PICORRELATION_SETCONTROL 0x0363
-#define CMD_FMR_DP_QUALITY_GETRESULT 0x05E3
-#define CMD_FMR_DP_QUALITY_START 0x05C3
-#define CMD_FMR_DP_SETCONTROL 0x02A3
-#define CMD_FMR_DP_SETEBLOCKREJECTION 0x02E3
-#define CMD_FMR_DP_SETGROUPREJECTION 0x0543
-#define CMD_FMR_GETSTATE 0x04E3
-#define CMD_FMR_RP_GETRSSI 0x0083
-#define CMD_FMR_RP_GETSTATE 0x0063
-#define CMD_FMR_RP_HIGHCUT_SETCONTROL 0x0263
-#define CMD_FMR_RP_HIGHCUT_SETMODE 0x0243
-#define CMD_FMR_RP_SETDEEMPHASIS 0x00C3
-#define CMD_FMR_RP_SETRSSIQUALITYTHRESHOLD 0x00A3
-#define CMD_FMR_RP_SOFTMUTE_SETCONTROL 0x0223
-#define CMD_FMR_RP_SOFTMUTE_SETMODE 0x0203
-#define CMD_FMR_RP_STEREO_SETCONTROL_BLENDINGPILOT 0x0163
-#define CMD_FMR_RP_STEREO_SETCONTROL_BLENDINGRSSI 0x0143
-#define CMD_FMR_RP_STEREO_SETMODE 0x0123
-#define CMD_FMR_RP_THRESHOLDEXTENSION_SETCONTROL 0x0103
-#define CMD_FMR_RP_THRESHOLDEXTENSION_SETMODE 0x00E3
-#define CMD_FMR_RP_XSTEREO_SETCONTROL 0x01E3
-#define CMD_FMR_RP_XSTEREO_SETMODE 0x01C3
-#define CMD_FMR_SETANTENNA 0x0663
-#define CMD_FMR_SETCOEXFILTER 0x06E3
-#define CMD_FMR_SETPROCESSINGMODE 0x0643
-#define CMD_FMR_SP_AFSWITCH_GETRESULT 0x0603
-#define CMD_FMR_SP_AFSWITCH_START 0x04A3
-#define CMD_FMR_SP_AFUPDATE_GETRESULT 0x0483
-#define CMD_FMR_SP_AFUPDATE_START 0x0463
+#define IRPT_INVALID 0x0000
+#define IRPT_OPERATIONSUCCEEDED 0x0001
+#define IRPT_OPERATIONFAILED 0x0002
+#define IRPT_RX_BUFFERFULL_TX_BUFFEREMPTY 0x0008
+#define IRPT_RX_SIGNALQUALITYLOW_MUTE_STATUS_CHANGED 0x0010
+#define IRPT_RX_MONOSTEREO_TRANSITION 0x0020
+#define IRPT_TX_OVERMODULATION 0x0030
+#define IRPT_RX_RDSSYNCFOUND_TX_OVERDRIVE 0x0040
+#define IRPT_RDSSYNCLOST 0x0080
+#define IRPT_PICODECHANGED 0x0100
+#define IRPT_REQUESTEDBLOCKAVAILABLE 0x0200
+#define IRPT_BUFFER_CLEARED 0x2000
+#define IRPT_WARMBOOTREADY 0x4000
+#define IRPT_COLDBOOTREADY 0x8000
+
+#define CMD_AIP_BT_SETCONTROL 0x01A6
+#define CMD_AIP_BT_SETMODE 0x01E6
+#define CMD_AIP_FADE_START 0x0046
+#define CMD_AIP_LEVEL_GETSTATUS 0x0106
+#define CMD_AIP_LEVEL_SETMODE 0x00E6
+#define CMD_AIP_OVERDRIVE_SETCONTROL 0x0166
+#define CMD_AIP_OVERDRIVE_SETMODE 0x0126
+#define CMD_AIP_SETAUDIOADC 0x00A6
+#define CMD_AIP_SETAUDIOADC_CONTROL 0x00C6
+#define CMD_AIP_SETBALANCE 0x0086
+#define CMD_AIP_SETGAIN 0x0066
+#define CMD_AIP_SETMIXER 0x0146
+#define CMD_AIP_SETMODE 0x01C6
+#define CMD_AUP_BT_SETBALANCE 0x0142
+#define CMD_AUP_BT_SETCONTROL 0x00E2
+#define CMD_AUP_BT_SETMODE 0x00C2
+#define CMD_AUP_BT_SETVOLUME 0x0122
+#define CMD_AUP_EXT_SETCONTROL 0x0182
+#define CMD_AUP_EXT_SETMODE 0x0162
+#define CMD_AUP_EXT_FADESTART 0x0102
+#define CMD_AUP_EXT_SETMUTE 0x01E2
+#define CMD_AUP_FADE_START 0x00A2
+#define CMD_AUP_SETAUDIODAC 0x0082
+#define CMD_AUP_SETBALANCE 0x0042
+#define CMD_AUP_SETMUTE 0x0062
+#define CMD_AUP_SETVOLUME 0x0022
+#define CMD_FMR_DP_BLOCKREQUEST_CONTROL 0x0583
+#define CMD_FMR_DP_BLOCKREQUEST_GETBLOCK 0x05A3
+#define CMD_FMR_DP_BUFFER_GETGROUP 0x0303
+#define CMD_FMR_DP_BUFFER_GETGROUPCOUNT 0x0323
+#define CMD_FMR_DP_BUFFER_SETSIZE 0x0343
+#define CMD_FMR_DP_BUFFER_SETTHRESHOLD 0x06C3
+#define CMD_FMR_DP_GETSTATE 0x0283
+#define CMD_FMR_DP_PICORRELATION_SETCONTROL 0x0363
+#define CMD_FMR_DP_QUALITY_GETRESULT 0x05E3
+#define CMD_FMR_DP_QUALITY_START 0x05C3
+#define CMD_FMR_DP_SETCONTROL 0x02A3
+#define CMD_FMR_DP_SETEBLOCKREJECTION 0x02E3
+#define CMD_FMR_DP_SETGROUPREJECTION 0x0543
+#define CMD_FMR_GETSTATE 0x04E3
+#define CMD_FMR_RP_GETRSSI 0x0083
+#define CMD_FMR_RP_GETSTATE 0x0063
+#define CMD_FMR_RP_HIGHCUT_SETCONTROL 0x0263
+#define CMD_FMR_RP_HIGHCUT_SETMODE 0x0243
+#define CMD_FMR_RP_SETDEEMPHASIS 0x00C3
+#define CMD_FMR_RP_SETRSSIQUALITYTHRESHOLD 0x00A3
+#define CMD_FMR_RP_SOFTMUTE_SETCONTROL 0x0223
+#define CMD_FMR_RP_SOFTMUTE_SETMODE 0x0203
+#define CMD_FMR_RP_STEREO_SETCONTROL_BLENDINGPILOT 0x0163
+#define CMD_FMR_RP_STEREO_SETCONTROL_BLENDINGRSSI 0x0143
+#define CMD_FMR_RP_STEREO_SETMODE 0x0123
+#define CMD_FMR_RP_THRESHOLDEXTENSION_SETCONTROL 0x0103
+#define CMD_FMR_RP_THRESHOLDEXTENSION_SETMODE 0x00E3
+#define CMD_FMR_RP_XSTEREO_SETCONTROL 0x01E3
+#define CMD_FMR_RP_XSTEREO_SETMODE 0x01C3
+#define CMD_FMR_SETANTENNA 0x0663
+#define CMD_FMR_SETCOEXFILTER 0x06E3
+#define CMD_FMR_SETPROCESSINGMODE 0x0643
+#define CMD_FMR_SP_AFSWITCH_GETRESULT 0x0603
+#define CMD_FMR_SP_AFSWITCH_START 0x04A3
+#define CMD_FMR_SP_AFUPDATE_GETRESULT 0x0483
+#define CMD_FMR_SP_AFUPDATE_START 0x0463
#define CMD_FMR_SP_BLOCKSCAN_GETRESULT 0x06A3
#define CMD_FMR_SP_BLOCKSCAN_START 0x0683
#define CMD_FMR_SP_PRESETPI_GETRESULT 0x0623
@@ -167,500 +163,507 @@
#define CMD_TST_TONE_SETPAR 0x0067
#define CMD_TST_TX_RAMP_START 0x0147
-/* Error/return codes */
-#define FMD_RESULT_SUCCESS 0x00
-#define FMD_RESULT_PRECONDITIONS_VIOLATED 0x01
-#define FMD_RESULT_PARAMETER_INVALID 0x02
-#define FMD_RESULT_IO_ERROR 0x04
-#define FMD_RESULT_FEATURE_UNSUPPORTED 0x05
-#define FMD_RESULT_BUSY 0x06
-#define FMD_RESULT_ONGOING 0x07
-#define FMD_RESULT_WAIT 0x08
-#define FMD_RESULT_RESPONSE_WRONG 0x09
-
-/* Frequency ranges */
-#define FMD_FREQRANGE_FMEUROAMERICA ((uint8_t) 0x01)
-#define FMD_FREQRANGE_FMJAPAN ((uint8_t) 0x02)
-#define FMD_FREQRANGE_FMCHINA ((uint8_t) 0x03)
-
-/* Callback event codes */
-#define FMD_EVENT_ANTENNA_STATUS_CHANGED ((uint32_t) 0x00000001)
-#define FMD_EVENT_FREQUENCY_CHANGED ((uint32_t) 0x00000002)
-#define FMD_EVENT_FREQUENCY_RANGE_CHANGED ((uint32_t) 0x00000003)
-#define FMD_EVENT_PRESET_CHANGED ((uint32_t) 0x00000004)
-#define FMD_EVENT_SEEK_COMPLETED ((uint32_t) 0x00000005)
-#define FMD_EVENT_SCAN_BAND_COMPLETED ((uint32_t) 0x00000006)
-#define FMD_EVENT_ACTION_FINISHED ((uint32_t) 0x00008001)
-#define FMD_EVENT_RDSGROUP_RCVD ((uint32_t) 0x00008002)
-#define FMD_EVENT_SEEK_STOPPED ((uint32_t) 0x00008003)
-#define FMD_EVENT_GEN_POWERUP ((uint32_t) 0x00008004)
-
-/* Stereo modes */
-#define FMD_STEREOMODE_MONO ((uint32_t) 0x00000000)
-#define FMD_STEREOMODE_STEREO ((uint32_t) 0x00000001)
-#define FMD_STEREOMODE_AUTO ((uint32_t) 0x00000002)
-
-/* Radio modes */
-#define FMD_MODE_IDLE 0x00
-#define FMD_MODE_RX 0x01
-#define FMD_MODE_TX 0x02
-
-/* FM Antenna selection */
-#define FMD_ANTENNA_EMBEDDED 0x00
-#define FMD_ANTENNA_WIRED 0x01
-
-/* FM tuning grid */
-#define FMD_GRID_50KHZ 0x00
-#define FMD_GRID_100KHZ 0x01
-#define FMD_GRID_200KHZ 0x02
-
-/* FM Deemphasis settings */
-#define FMD_EMPHASIS_50US 0x01
-#define FMD_EMPHASIS_75US 0x02
-
-/* Mixer modes */
-#define FMD_MIXERMODE_PASS ((uint32_t) 0x00000000)
-#define FMD_MIXERMODE_SUM ((uint32_t) 0x00000001)
-#define FMD_MIXERMODE_LEFT ((uint32_t) 0x00000002)
-#define FMD_MIXERMODE_RIGHT ((uint32_t) 0x00000003)
-
-#define FMD_AUTOMUTEMODE_OFF ((uint32_t) 0x00000000)
-#define FMD_AUTOMUTEMODE_ON ((uint32_t) 0x00000001)
-#define FMD_AUTOMUTEMODE_AUTOMATIC ((uint32_t) 0x00000002)
-
-#define FMD_AUTOMUTETYPE_MUTE ((uint32_t) 0x00000000)
-#define FMD_AUTOMUTETYPE_RDS ((uint32_t) 0x00000001)
-
-/* Output of BT sample Rate Convertor */
-#define FMD_OUTPUT_DISABLED 0x00
-#define FMD_OUTPUT_I2S 0x01
-#define FMD_OUTPUT_PARALLEL 0x02
-#define FMD_OUTPUT_FIFO 0x03
-
-/* on Off States for RDS */
-#define FMD_SWITCH_OFF_RDS_SIMULATOR 0x00
-#define FMD_SWITCH_OFF_RDS 0x01
-#define FMD_SWITCH_ON_RDS 0x02
-#define FMD_SWITCH_ON_RDS_ENHANCED_MODE 0x03
-
-#define ST_WRITE_FILE_BLK_SIZE 254
-#define CATENA_OPCODE 0xFE
-
-#define FM_WRITE 0x00
-#define FM_READ 0x01
+#define ST_WRITE_FILE_BLK_SIZE 254
+#define CATENA_OPCODE 0xFE
-/* HCI Events */
-#define HCI_COMMAND_COMPLETE_EVENT 0x0E
-#define HCI_VS_DBG_EVENT 0xFF
+#define FM_WRITE 0x00
+#define FM_READ 0x01
+/* HCI Events */
+#define HCI_COMMAND_COMPLETE_EVENT 0x0E
+#define HCI_VS_DBG_EVENT 0xFF
/* HCI Packets indicators */
-#define HCI_PACKET_INDICATOR_CMD 0x01
- #define HCI_PACKET_INDICATOR_EVENT 0x04
- #define HCI_PACKET_INDICATOR_FM_CMD_EVT 0x08
+#define HCI_PACKET_INDICATOR_CMD 0x01
+ #define HCI_PACKET_INDICATOR_EVENT 0x04
+ #define HCI_PACKET_INDICATOR_FM_CMD_EVT 0x08
/* HCI Command opcodes */
-#define HCI_CMD_FM 0xFD50
-#define HCI_CMD_VS_WRITE_FILE_BLOCK 0xFC2E
-#define FM_EVENT 0x15
-
-#define FM_FUNCTION_ENABLE 0x00
-#define FM_FUNCTION_DISABLE 0x01
-#define FM_FUNCTION_RESET 0x02
-#define FM_FUNCTION_WRITECOMMAND 0x10
-#define FM_FUNCTION_SETINTMASKALL 0x20
-#define FM_FUNCTION_GETINTMASKALL 0x21
-#define FM_FUNCTION_SETINTMASK 0x22
-#define FM_FUNCTION_GETINTMASK 0x23
-#define FM_FUNCTION_FMFWDOWNLOAD 0x30
-
-/* FM status in return parameter Size: 1 Byte */
-
-/* Command succeeded */
-#define FM_CMD_STATUS_CMD_SUCCESS 0x00
-/* HCI_ERR_HW_FAILURE when no response from the IP.8 */
-#define FM_CMD_STATUS_HCI_ERR_HW_FAILURE 0x03
+#define HCI_CMD_FM 0xFD50
+#define HCI_CMD_VS_WRITE_FILE_BLOCK 0xFC2E
+#define FM_EVENT 0x15
+
+#define FM_FUNCTION_ENABLE 0x00
+#define FM_FUNCTION_DISABLE 0x01
+#define FM_FUNCTION_RESET 0x02
+#define FM_FUNCTION_WRITECOMMAND 0x10
+#define FM_FUNCTION_SETINTMASKALL 0x20
+#define FM_FUNCTION_GETINTMASKALL 0x21
+#define FM_FUNCTION_SETINTMASK 0x22
+#define FM_FUNCTION_GETINTMASK 0x23
+#define FM_FUNCTION_FMFWDOWNLOAD 0x30
+
+/* FM status in return parameter Size: 1 Byte */
+
+/* Command succeeded */
+#define FM_CMD_STATUS_CMD_SUCCESS 0x00
+/* HCI_ERR_HW_FAILURE when no response from the IP */
+#define FM_CMD_STATUS_HCI_ERR_HW_FAILURE 0x03
/* HCI_ERR_INVALID_PARAMETERS. */
-#define FM_CMD_STATUS_HCI_ERR_INVALID_PARAMETERS 0x12
+#define FM_CMD_STATUS_HCI_ERR_INVALID_PARAMETERS 0x12
/* When the host tries to send a command to an IP that hasn't been
* initialized.
*/
-#define FM_CMD_STATUS_IP_UNINIT 0x15
-/* HCI_ERR_UNSPECIFIED_ERROR: any other error */
-#define FM_CMD_STATUS_HCI_ERR_UNSPECIFIED_ERROR 0x1F
+#define FM_CMD_STATUS_IP_UNINIT 0x15
+/* HCI_ERR_UNSPECIFIED_ERROR: any other error */
+#define FM_CMD_STATUS_HCI_ERR_UNSPECIFIED_ERROR 0x1F
/* HCI_ERR_CMD_DISALLOWED when the host asks for an unauthorized operation
* (FM state transition for instance)
*/
-#define FM_CMD_STATUS_HCI_ERR_CMD_DISALLOWED 0x0C
-/* Wrong sequence number for FM FW download command */
-#define FM_CMD_STATUS_WRONG_SEQ_NUM 0xF1
-/* Unknown file type for FM FW download command */
-#define FM_CMD_STATUS_UNKOWNFILE_TYPE 0xF2
-/* File version mismatch for FM FW download command */
-#define FM_CMD_STATUS_FILE_VERSION_MISMATCH 0xF3
+#define FM_CMD_STATUS_HCI_ERR_CMD_DISALLOWED 0x0C
+/* Wrong sequence number for FM FW download command */
+#define FM_CMD_STATUS_WRONG_SEQ_NUM 0xF1
+/* Unknown file type for FM FW download command */
+#define FM_CMD_STATUS_UNKOWNFILE_TYPE 0xF2
+/* File version mismatch for FM FW download command */
+#define FM_CMD_STATUS_FILE_VERSION_MISMATCH 0xF3
+
+/**
+ * enum fmd_status_t - Status of some operations.
+ * @FMD_RESULT_SUCCESS: Current operation is completed with success.
+ * @FMD_RESULT_PRECONDITIONS_VIOLATED: Frequency has been changed.
+ * @FMD_RESULT_PARAMETER_INVALID: Frequency Range has been changed.
+ * @FMD_RESULT_IO_ERROR: Seek operation has completed.
+ * @FMD_RESULT_FEATURE_UNSUPPORTED: Band Scan Completed.
+ * @FMD_RESULT_BUSY: Block Scan completed.
+ * @FMD_RESULT_ONGOING: Af Update or AF Switch is complete.
+ * stopped.
+ * @FMD_RESULT_RESPONSE_WRONG: FM IP Powerup has been powered up.
+ * Various status returned for any operation by FM Driver.
+ */
+enum fmd_status_t {
+ FMD_RESULT_SUCCESS,
+ FMD_RESULT_PRECONDITIONS_VIOLATED,
+ FMD_RESULT_PARAMETER_INVALID,
+ FMD_RESULT_IO_ERROR,
+ FMD_RESULT_FEATURE_UNSUPPORTED,
+ FMD_RESULT_BUSY,
+ FMD_RESULT_ONGOING,
+ FMD_RESULT_RESPONSE_WRONG
+};
+
+/**
+ * enum fmd_event_t - Events received.
+ * @FMD_EVENT_ANTENNA_STATUS_CHANGED: Antenna has been changed.
+ * @FMD_EVENT_FREQUENCY_CHANGED: Frequency has been changed.
+ * @FMD_EVENT_SEEK_COMPLETED: Seek operation has completed.
+ * @FMD_EVENT_SCAN_BAND_COMPLETED: Band Scan Completed.
+ * @FMD_EVENT_BLOCK_SCAN_COMPLETED: Block Scan completed.
+ * @FMD_EVENT_AF_UPDATE_SWITCH_COMPLETE: Af Update or AF Switch is complete.
+ * @FMD_EVENT_MONOSTEREO_TRANSITION_COMPLETE: Mono stereo transition is
+ * completed.
+ * @FMD_EVENT_SEEK_STOPPED: Previous Seek/Band Scan/ Block Scan operation is
+ * stopped.
+ * @FMD_EVENT_GEN_POWERUP: FM IP Powerup has been powered up.
+ * @FMD_EVENT_RDSGROUP_RCVD: RDS Groups Full interrupt.
+ * @FMD_EVENT_LAST_ELEMENT: Last event, used for keeping count of
+ * number of events.
+ * Various events received from Fm driver for Upper Layer(s) processing.
+ */
+enum fmd_event_t {
+ FMD_EVENT_ANTENNA_STATUS_CHANGED,
+ FMD_EVENT_FREQUENCY_CHANGED,
+ FMD_EVENT_SEEK_COMPLETED,
+ FMD_EVENT_SCAN_BAND_COMPLETED,
+ FMD_EVENT_BLOCK_SCAN_COMPLETED,
+ FMD_EVENT_AF_UPDATE_SWITCH_COMPLETE,
+ FMD_EVENT_MONOSTEREO_TRANSITION_COMPLETE,
+ FMD_EVENT_SEEK_STOPPED,
+ FMD_EVENT_GEN_POWERUP,
+ FMD_EVENT_RDSGROUP_RCVD,
+ FMD_EVENT_LAST_ELEMENT
+};
+
+/**
+ * enum fmd_mode_t - FM Driver Modes.
+ * @FMD_MODE_IDLE: FM Driver in Idle mode.
+ * @FMD_MODE_RX: FM Driver in Rx mode.
+ * @FMD_MODE_TX: FM Driver in Tx mode.
+ * Various Modes of FM Radio.
+ */
+enum fmd_mode_t {
+ FMD_MODE_IDLE,
+ FMD_MODE_RX,
+ FMD_MODE_TX
+};
+
+/**
+ * enum fmd_antenna_t - Antenna selection.
+ * @FMD_ANTENNA_EMBEDDED: Embedded Antenna.
+ * @FMD_ANTENNA_WIRED: Wired Antenna.
+ * Antenna to be used for FM Radio.
+ */
+enum fmd_antenna_t {
+ FMD_ANTENNA_EMBEDDED,
+ FMD_ANTENNA_WIRED
+};
+
+/**
+ * enum fmd_grid_t - Grid used on FM Radio.
+ * @FMD_GRID_50KHZ: 50 kHz grid spacing.
+ * @FMD_GRID_100KHZ: 100 kHz grid spacing.
+ * @FMD_GRID_200KHZ: 200 kHz grid spacing.
+ * Spacing used on FM Radio.
+ */
+enum fmd_grid_t {
+ FMD_GRID_50KHZ,
+ FMD_GRID_100KHZ,
+ FMD_GRID_200KHZ
+};
+
+/**
+ * enum fmd_emphasis_t - De-emphasis/Pre-emphasis level.
+ * @FMD_EMPHASIS_50US: 50 us de-emphasis/pre-emphasis level.
+ * @FMD_EMPHASIS_75US: 100 us de-emphasis/pre-emphasi level.
+ * De-emphasis/Pre-emphasis level used on FM Radio.
+ */
+enum fmd_emphasis_t {
+ FMD_EMPHASIS_50US,
+ FMD_EMPHASIS_75US
+};
+
+/**
+ * enum fmd_freq_range_t - Frequency range.
+ * @FMD_FREQRANGE_EUROAMERICA: EU/US Range (87.5 - 108 MHz).
+ * @FMD_FREQRANGE_JAPAN: Japan Range (76 - 90 MHz).
+ * @FMD_FREQRANGE_CHINA: China Range (70 - 108 MHz).
+ * Various Frequency range(s) supported by FM Radio.
+ */
+enum fmd_freq_range_t {
+ FMD_FREQRANGE_EUROAMERICA,
+ FMD_FREQRANGE_JAPAN,
+ FMD_FREQRANGE_CHINA
+};
+
+/**
+ * enum fmd_stereo_mode_t - FM Driver Stereo Modes.
+ * @FMD_STEREOMODE_OFF: Streo Blending Off.
+ * @FMD_STEREOMODE_MONO: Mono Mode.
+ * @FMD_STEREOMODE_BLENDING: Blending Mode.
+ * Various Stereo Modes of FM Radio.
+ */
+enum fmd_stereo_mode_t {
+ FMD_STEREOMODE_OFF,
+ FMD_STEREOMODE_MONO,
+ FMD_STEREOMODE_BLENDING
+};
+
+/*Remove the below two enum w.r.t audio_config redundancy*/
+
+ /**
+ * enum fmd_output_t - Output of Sample Rate Converter.
+ * @FMD_OUTPUT_DISABLED: Sample Rate converter in disabled.
+ * @FMD_OUTPUT_I2S: I2S Output from Sample rate converter.
+ * @FMD_OUTPUT_PARALLEL: Parallel output from sample rate converter.
+ * Sample Rate Converter's output to be set on Connectivity Controller.
+ */
+enum fmd_output_t {
+ FMD_OUTPUT_DISABLED,
+ FMD_OUTPUT_I2S,
+ FMD_OUTPUT_PARALLEL
+};
+
+ /**
+ * enum fmd_input_t - Audio Input to Sample Rate Converter.
+ * @FMD_INPUT_ANALOG: Selects the ADC's as audio source
+ * @FMD_INPUT_DIGITAL: Selects Digital Input as audio source.
+ * Audio Input source for Sample Rate Converter.
+ */
+enum fmd_input_t {
+ FMD_INPUT_ANALOG,
+ FMD_INPUT_DIGITAL
+};
+
+
+/**
+* enum fmd_rds_mode_t - RDS Mode to be selected for FM Rx.
+* @FMD_SWITCH_OFF_RDS: RDS Decoding disabled in FM Chip.
+* @FMD_SWITCH_ON_RDS: RDS Decoding enabled in FM Chip.
+* @FMD_SWITCH_ON_RDS_ENHANCED_MODE: Enhanced RDS Mode.
+* @FMD_SWITCH_ON_RDS_SIMULATOR: RDS Simulator switched on in FM Chip.
+* RDS Mode to be selected for FM Rx.
+*/
+enum fmd_rds_mode_t {
+ FMD_SWITCH_OFF_RDS,
+ FMD_SWITCH_ON_RDS,
+ FMD_SWITCH_ON_RDS_ENHANCED_MODE,
+ FMD_SWITCH_ON_RDS_SIMULATOR
+};
/* Callback function to receive radio events. */
typedef void(*fmd_radio_cb)(
void *context,
- uint32_t event,
- uint32_t event_int_data,
- bool event_boolean_data
+ u8 event,
+ bool event_successful
);
/**
* fmd_init() - Initialize the FM Driver internal structures.
- * @context: (out) Pointer to Pointer of FM Driver Context
+ * @context: (out) FM Driver Context
* Returns:
* FMD_RESULT_SUCCESS, if no error.
* FMD_RESULT_IO_ERROR, if there is an error.
*/
-uint8_t fmd_init(
+u8 fmd_init(
void **context
);
/**
+ * fmd_deinit() - De-initialize the FM Driver.
+ */
+void fmd_deinit(void);
+
+/**
* fmd_register_callback() - Function to register callback function.
- * This fucntion registers the callback function provided by upper layers.
- * @context: Pointer to FM Driver Context
+ * This function registers the callback function provided by upper layers.
+ * @context: FM Driver Context
* @callback: Fmradio call back Function pointer
* Returns:
* FMD_RESULT_SUCCESS, if no error.
* FMD_RESULT_IO_ERROR, if there is an error.
* FMD_RESULT_BUSY, if FM Driver is not in idle state.
*/
-uint8_t fmd_register_callback(
+u8 fmd_register_callback(
void *context,
fmd_radio_cb callback
);
/**
- * fmd_get_version() - Retrives the FM HW and FW version.
- * @context: Pointer to FM Driver Context
- * @version: Version Array
+ * fmd_get_version() - Retrieves the FM HW and FW version.
+ * @context: FM Driver Context
+ * @version: (out) Version Array
* Returns:
* FMD_RESULT_SUCCESS, if no error.
* FMD_RESULT_IO_ERROR, if there is an error.
* FMD_RESULT_BUSY, if FM Driver is not in idle state.
* FMD_RESULT_RESPONSE_WRONG, if wrong response received from chip.
*/
-uint8_t fmd_get_version(
+u8 fmd_get_version(
void *context,
- uint16_t version[]
+ u16 version[7]
);
/**
* fmd_set_mode() - Starts a transition to the given mode.
- * @context: Pointer to FM Driver Context
+ * @context: FM Driver Context
* @mode: Transition mode
* Returns:
- * FMD_RESULT_WAIT, if no error.
+ * FMD_RESULT_SUCCESS, if set mode done successfully.
+ * FMD_RESULT_PARAMETER_INVALID, if parameter is invalid.
* FMD_RESULT_IO_ERROR, if there is an error.
* FMD_RESULT_RESPONSE_WRONG, if wrong response received from chip.
*/
-uint8_t fmd_set_mode(
+u8 fmd_set_mode(
void *context,
- uint8_t mode
+ u8 mode
);
/**
- * fmd_get_mode() - Gets the current mode.
- * @context: Pointer to FM Driver Context
- * @mode: Current Transition mode
- * Returns:
- * FMD_RESULT_SUCCESS, if no error.
- * FMD_RESULT_IO_ERROR, if there is an error.
- * FMD_RESULT_BUSY, if FM Driver is not in idle state.
- * FMD_RESULT_RESPONSE_WRONG, if wrong response received from chip.
- */
-
-uint8_t fmd_get_mode(
- void *context,
- uint8_t *mode
- );
-
-/**
- * fmd_is_freq_range_supported() - Checks if Freq range is supported or not.
- * @context: Pointer to FM Driver Context
+ * fmd_get_freq_range_properties() - Retrieves Freq Range Properties.
+ * @context: FM Driver Context
* @range: range of freq
- * @supported:Available freq range.
+ * @minfreq: (out) Minimum Frequency of the Band in kHz.
+ * @maxfreq: (out) Maximum Frequency of the Band in kHz
* Returns:
* FMD_RESULT_SUCCESS, if no error.
* FMD_RESULT_IO_ERROR, if there is an error.
* FMD_RESULT_BUSY, if FM Driver is not in idle state.
*/
-uint8_t fmd_is_freq_range_supported(
+u8 fmd_get_freq_range_properties(
void *context,
- uint8_t range,
- bool *supported
- );
-
-/**
- * fmd_get_freq_range_properties() - Retrives Freq Range Properties.
- * @context: Pointer to FM Driver Context
- * @range: range of freq
- * @minfreq: Pointer to Minimum Frequency of the Band
- * @maxfreq: Pointer to Maximum Frequency of the Band
- * @freqinterval: Pointer to the Frequency Interval
- * Returns:
- * FMD_RESULT_SUCCESS, if no error.
- * FMD_RESULT_IO_ERROR, if there is an error.
- * FMD_RESULT_BUSY, if FM Driver is not in idle state.
- */
-uint8_t fmd_get_freq_range_properties(
- void *context,
- uint8_t range,
- uint32_t *minfreq,
- uint32_t *maxfreq,
- uint32_t *freqinterval
+ u8 range,
+ u32 *minfreq,
+ u32 *maxfreq
);
/**
* fmd_set_antenna() - Selects the antenna to be used in receive mode.
* embedded - Selects the embedded antenna, wired- Selects the wired antenna.
- * @context: Pointer to FM Driver Context
- * @ant: Antenna Type
+ * @context: FM Driver Context
+ * @antenna: Antenna Type
* Returns:
- * FMD_RESULT_WAIT, if set antenna started successfully.
+ * FMD_RESULT_SUCCESS, if set antenna done successfully.
+ * FMD_RESULT_PARAMETER_INVALID, if parameter is invalid.
* FMD_RESULT_IO_ERROR, if there is an error.
* FMD_RESULT_BUSY, if FM Driver is not in idle state.
* FMD_RESULT_RESPONSE_WRONG, if wrong response received from chip.
*/
-uint8_t fmd_set_antenna(
+u8 fmd_set_antenna(
void *context,
- uint8_t ant
+ u8 antenna
);
/**
- * fmd_get_antenna() - Retrives the currently used antenna type.
- * @context: Pointer to FM Driver Context
- * @ant: Pointer to Antenna
+ * fmd_get_antenna() - Retrieves the currently used antenna type.
+ * @context: FM Driver Context
+ * @antenna: (out) Antenna Selected on FM Radio.
* Returns:
* FMD_RESULT_SUCCESS, if no error.
* FMD_RESULT_IO_ERROR, if there is an error.
* FMD_RESULT_BUSY, if FM Driver is not in idle state.
*/
-uint8_t fmd_get_antenna(
+u8 fmd_get_antenna(
void *context,
- uint8_t *ant
+ u8 *antenna
);
/**
* fmd_set_freq_range() - Sets the FM band.
- * @context: Pointer to FM Driver Context
+ * @context: FM Driver Context
* @range: freq range
* Returns:
* FMD_RESULT_SUCCESS, if no error.
+ * FMD_RESULT_PARAMETER_INVALID, if parameter is invalid.
* FMD_RESULT_IO_ERROR, if there is an error.
* FMD_RESULT_BUSY, if FM Driver is not in idle state.
* FMD_RESULT_RESPONSE_WRONG, if wrong response received from chip.
*/
-uint8_t fmd_set_freq_range(
+u8 fmd_set_freq_range(
void *context,
- uint8_t range
+ u8 range
);
/**
* fmd_get_freq_range() - Gets the FM band currently in use.
- * @context: Pointer to FM Driver Context
- * @range: Pointer to base freq range.
+ * @context: FM Driver Context
+ * @range: (out) Frequency Range set on FM Radio.
* Returns:
* FMD_RESULT_SUCCESS, if no error.
* FMD_RESULT_IO_ERROR, if there is an error.
* FMD_RESULT_BUSY, if FM Driver is not in idle state.
*/
-uint8_t fmd_get_freq_range(
+u8 fmd_get_freq_range(
void *context,
- uint8_t *range
+ u8 *range
);
/**
* fmd_rx_set_grid() - Sets the tuning grid.
- * @context: Pointer to FM Driver Context
+ * @context: FM Driver Context
* @grid: Tuning grid size
* Returns:
* FMD_RESULT_SUCCESS, if no error.
+ * FMD_RESULT_PARAMETER_INVALID, if parameter is invalid.
* FMD_RESULT_IO_ERROR, if there is an error.
* FMD_RESULT_BUSY, if FM Driver is not in idle state.
* FMD_RESULT_RESPONSE_WRONG, if wrong response received from chip.
*/
-uint8_t fmd_rx_set_grid(
- void *context,
- uint8_t grid
- );
-
-/**
- * fmd_rx_get_grid() - Gets the current tuning grid.
- * @context: Pointer to FM Driver Context
- * @grid: pointer to base Grid to be retrieved.
- * Returns:
- * FMD_RESULT_SUCCESS, if no error.
- * FMD_RESULT_IO_ERROR, if there is an error.
- * FMD_RESULT_BUSY, if FM Driver is not in idle state.
- */
-uint8_t fmd_rx_get_grid(
- void *context,
- uint8_t *grid
- );
-
-/**
- * fmd_rx_set_deemphasis() - Sets the De-emphasis level.
- * Sets the de-emphasis characteristic of the receiver
- * FMD_EMPHASIS_50US & FMD_EMPHASIS_75US.
- * @context: Pointer to FM Driver Context
- * @deemphasis: Char of Rx level.
- * Returns:
- * FMD_RESULT_SUCCESS, if no error.
- * FMD_RESULT_IO_ERROR, if there is an error.
- * FMD_RESULT_BUSY, if FM Driver is not in idle state.
- * FMD_RESULT_RESPONSE_WRONG, if wrong response received from chip.
- */
-uint8_t fmd_rx_set_deemphasis(
+u8 fmd_rx_set_grid(
void *context,
- uint8_t deemphasis
- );
-
-/**
- * fmd_rx_get_deemphasis() - Get the De-emphasis level.
- * Gets the currently used de-emphasis characteristic
- * of the receiver FMD_EMPHASIS_50US & FMD_EMPHASIS_75US.
- * @context: Pointer to FM Driver Context
- * @deemphasis: Pointer to base De-emphasis.
- * Returns:
- * FMD_RESULT_SUCCESS, if no error.
- * FMD_RESULT_IO_ERROR, if there is an error.
- * FMD_RESULT_BUSY, if FM Driver is not in idle state.
- */
-uint8_t fmd_rx_get_deemphasis(
- void *context,
- uint8_t *deemphasis
+ u8 grid
);
/**
* fmd_rx_set_frequency() - Sets the FM Channel.
- * @context: Pointer to FM Driver Context
+ * @context: FM Driver Context
* @freq: Frequency to Set in Khz
* Returns:
- * FMD_RESULT_WAIT, if set frequency operation started
- * successfully.
+ * FMD_RESULT_SUCCESS, if set frequency done successfully.
* FMD_RESULT_IO_ERROR, if there is an error.
* FMD_RESULT_BUSY, if FM Driver is not in idle state.
* FMD_RESULT_RESPONSE_WRONG, if wrong response received from chip.
*/
-uint8_t fmd_rx_set_frequency(
+u8 fmd_rx_set_frequency(
void *context,
- uint32_t freq
+ u32 freq
);
/**
* fmd_rx_get_frequency() - Gets the currently used FM Channel.
- * @context: Pointer to FM Driver Context
- * @freq: Pointer to base freq
+ * @context: FM Driver Context
+ * @freq: (out) Current Frequency set on FM Radio.
* Returns:
* FMD_RESULT_SUCCESS, if no error.
* FMD_RESULT_IO_ERROR, if there is an error.
* FMD_RESULT_BUSY, if FM Driver is not in idle state.
* FMD_RESULT_RESPONSE_WRONG, if wrong response received from chip.
*/
-uint8_t fmd_rx_get_frequency(
+u8 fmd_rx_get_frequency(
void *context,
- uint32_t *freq
+ u32 *freq
);
/**
* fmd_rx_set_stereo_mode() - Sets the stereomode functionality.
- * @context: Pointer to FM Driver Context
+ * @context: FM Driver Context
* @mode: FMD_STEREOMODE_MONO, FMD_STEREOMODE_STEREO and
* Returns:
* FMD_RESULT_SUCCESS, if no error.
+ * FMD_RESULT_PARAMETER_INVALID, if parameter is invalid.
* FMD_RESULT_IO_ERROR, if there is an error.
* FMD_RESULT_BUSY, if FM Driver is not in idle state.
* FMD_RESULT_RESPONSE_WRONG, if wrong response received from chip.
*/
-uint8_t fmd_rx_set_stereo_mode(
+u8 fmd_rx_set_stereo_mode(
void *context,
- uint32_t mode
+ u8 mode
);
/**
* fmd_rx_get_stereo_mode() - Gets the currently used FM mode.
* FMD_STEREOMODE_MONO, FMD_STEREOMODE_STEREO and
* FMD_STEREOMODE_AUTO.
- * @context: Pointer to FM Driver Context
- * @mode: Pointer to mode
+ * @context: FM Driver Context
+ * @mode: (out) Mode set on FM Radio, stereo or mono.
* Returns:
* FMD_RESULT_SUCCESS, if no error.
* FMD_RESULT_IO_ERROR, if there is an error.
* FMD_RESULT_BUSY, if FM Driver is not in idle state.
*/
-uint8_t fmd_rx_get_stereo_mode(
+u8 fmd_rx_get_stereo_mode(
void *context,
- uint32_t *mode
+ u8 *mode
);
/**
* fmd_rx_get_signal_strength() - Gets the RSSI level of current frequency.
- * @context: Pointer to FM Driver Context
- * @strength: Pointer to base Strength
- * Returns:
- * FMD_RESULT_SUCCESS, if no error.
- * FMD_RESULT_IO_ERROR, if there is an error.
- * FMD_RESULT_BUSY, if FM Driver is not in idle state.
- * FMD_RESULT_RESPONSE_WRONG, if wrong response received from chip.
- */
-uint8_t fmd_rx_get_signal_strength(
- void *context,
- uint32_t *strength
- );
-
-/**
- * fmd_rx_get_pilot_state() - Gets Pilot State.
- * @context: Pointer to FM Driver Context
- * @on: Pointer to Pilot state for FM Rx.
+ * @context: FM Driver Context
+ * @strength: (out) RSSI level of current channel.
* Returns:
* FMD_RESULT_SUCCESS, if no error.
* FMD_RESULT_IO_ERROR, if there is an error.
* FMD_RESULT_BUSY, if FM Driver is not in idle state.
* FMD_RESULT_RESPONSE_WRONG, if wrong response received from chip.
*/
-uint8_t fmd_rx_get_pilot_state(
+u8 fmd_rx_get_signal_strength(
void *context,
- bool *on
+ u16 *strength
);
/**
* fmd_rx_set_stop_level() - Sets the FM Rx Seek stop level.
- * @context: Pointer to FM Driver Context
+ * @context: FM Driver Context
* @stoplevel: seek stop level
* Returns:
* FMD_RESULT_SUCCESS, if no error.
* FMD_RESULT_IO_ERROR, if there is an error.
* FMD_RESULT_BUSY, if FM Driver is not in idle state.
*/
-uint8_t fmd_rx_set_stop_level(
+u8 fmd_rx_set_stop_level(
void *context,
- uint16_t stoplevel
+ u16 stoplevel
);
/**
* fmd_rx_get_stop_level() - Gets the current FM Rx Seek stop level.
- * @context: Pointer to FM Driver Context
- * @stoplevel: Pointer to base stop level
+ * @context: FM Driver Context
+ * @stoplevel: (out) RSSI Threshold set on FM Radio.
* Returns:
* FMD_RESULT_SUCCESS, if no error.
* FMD_RESULT_IO_ERROR, if there is an error.
* FMD_RESULT_BUSY, if FM Driver is not in idle state.
*/
-uint8_t fmd_rx_get_stop_level(
+u8 fmd_rx_get_stop_level(
void *context,
- uint16_t *stoplevel
+ u16 *stoplevel
);
/**
* fmd_rx_seek() - Perform FM Seek.
* Starts searching relative to the actual channel with
* a specific direction, stop.
- * @context: Pointer to FM Driver Context
+ * @context: FM Driver Context
* level and optional noise levels
* @upwards: scan up
* Returns:
@@ -669,110 +672,207 @@ uint8_t fmd_rx_get_stop_level(
* FMD_RESULT_BUSY, if FM Driver is not in idle state.
* FMD_RESULT_RESPONSE_WRONG, if wrong response received from chip.
*/
-uint8_t fmd_rx_seek(
+u8 fmd_rx_seek(
void *context,
bool upwards
);
/**
* fmd_rx_stop_seeking() - Stops a currently active seek or scan band.
- * @context: Pointer to FM Driver Context
+ * @context: FM Driver Context
* Returns:
- * FMD_RESULT_WAIT, if stop seek started successfully.
+ * FMD_RESULT_SUCCESS, if stop seek done successfully.
* FMD_RESULT_IO_ERROR, if there is an error.
* FMD_RESULT_PRECONDITIONS_VIOLATED, if FM Driver is
* not currently in Seek or Scan State..
* FMD_RESULT_RESPONSE_WRONG, if wrong response received from chip.
*/
-uint8_t fmd_rx_stop_seeking(
+u8 fmd_rx_stop_seeking(
void *context
);
/**
+ * fmd_rx_af_update_start() - Perform AF update.
+ * This is used to switch to a shortly tune to a AF freq,
+ * measure its RSSI and tune back to the original frequency.
+ * @context: FM Driver Context
+ * @freq: Alternative frequncy in KHz to be set for AF updation.
+ * Returns:
+ * FMD_RESULT_BUSY, if FM Driver is not in idle state.
+ * FMD_RESULT_SUCCESS, if no error.
+ * FMD_RESULT_IO_ERROR, if there is an error.
+ */
+u8 fmd_rx_af_update_start(
+ void *context,
+ u32 freq
+ );
+
+/**
+ * fmd_rx_get_af_update_result() - Retrive result of AF update.
+ * Retrive the RSSI level of the Alternative frequency.
+ * @context: FM Driver Context
+ * @af_level: RSSI level of the Alternative frequency.
+ * Returns:
+ * FMD_RESULT_BUSY, if FM Driver is not in idle state.
+ * FMD_RESULT_SUCCESS, if no error.
+ * FMD_RESULT_IO_ERROR, if there is an error.
+ */
+u8 fmd_rx_get_af_update_result(
+ void *context,
+ u16 *af_level
+ );
+
+
+/**
+ * fmd_af_switch_start() -Performs AF switch.
+ * @context: FM Driver Context
+ * @freq: Frequency to Set in Khz.
+ * @picode:programable id,unique for each station.
+ *
+ * Returns:
+ * FMD_RESULT_BUSY, if FM Driver is not in idle state.
+ * FMD_RESULT_SUCCESS, if no error.
+ * FMD_RESULT_SUCCESS, if AF switch started successfully.
+ * FMD_RESULT_IO_ERROR, if there is an error.
+ */
+u8 fmd_rx_af_switch_start(
+ void *context,
+ u32 freq,
+ u16 picode
+ );
+
+/**
+ * fmd_rx_get_af_switch_results() -Retrieves the results of AF Switch.
+ * @context: FM Driver Context
+ * @afs_conclusion: Conclusion of AF switch.
+ * @afs_level: RSSI level of the Alternative frequnecy.
+ * @afs_pi: PI code of the alternative channel (if found).
+ * Returns:
+ * FMD_RESULT_BUSY, if FM Driver is not in idle state.
+ * FMD_RESULT_SUCCESS, if no error.
+ * FMD_RESULT_IO_ERROR, if there is an error.
+ */
+u8 fmd_rx_get_af_switch_results(
+ void *context,
+ u16 *afs_conclusion,
+ u16 *afs_level,
+ u16 *afs_pi
+ );
+
+/**
* fmd_rx_scan_band() - Starts Band Scan.
* Starts scanning the active band for the strongest
* channels above a threshold.
- * @context: Pointer to FM Driver Context
+ * @context: FM Driver Context
+ * @max_channels_to_scan: Maximum number of channels to scan.
* Returns:
* FMD_RESULT_ONGOING, if scan band started successfully.
* FMD_RESULT_IO_ERROR, if there is an error.
* FMD_RESULT_BUSY, if FM Driver is not in idle state.
* FMD_RESULT_RESPONSE_WRONG, if wrong response received from chip.
*/
-uint8_t fmd_rx_scan_band(
- void *context
+u8 fmd_rx_scan_band(
+ void *context,
+ u8 max_channels_to_scan
+ );
+
+/**
+ * fmd_rx_get_max_channels_to_scan() - Retreives the maximum channels.
+ * Retrieves the maximum number of channels that can be found during
+ * band scann.
+ * @context: FM Driver Context
+ * @max_channels_to_scan: (out) Maximum number of channels to scan.
+ * Returns:
+ * FMD_RESULT_BUSY, if FM Driver is not in idle state.
+ * FMD_RESULT_RESPONSE_WRONG, if wrong response received from chip.
+ */
+u8 fmd_rx_get_max_channels_to_scan(
+ void *context,
+ u8 *max_channels_to_scan
);
/**
* fmd_rx_get_scan_band_info() - Retrieves Channels found during scanning.
- * Retrives the scanned active band
+ * Retrieves the scanned active band
* for the strongest channels above a threshold.
- * @context: Pointer to FM Driver Context
- * @index: Index value to retrieve the channels.
- * @numchannels: Pointer to Number of channels found
- * @channels: Pointer to channels found
- * @rssi: Pointer to rssi of channels found
+ * @context: FM Driver Context
+ * @index: (out) Index value to retrieve the channels.
+ * @numchannels: (out) Number of channels found during Band Scan.
+ * @channels: (out) Channels found during band scan.
+ * @rssi: (out) Rssi of channels found during Band scan.
* Returns:
* FMD_RESULT_ONGOING, if no error.
* FMD_RESULT_IO_ERROR, if there is an error.
* FMD_RESULT_RESPONSE_WRONG, if wrong response received from chip.
*/
-uint8_t fmd_rx_get_scan_band_info(
+u8 fmd_rx_get_scan_band_info(
void *context,
- uint32_t index,
- uint16_t *numchannels,
- uint16_t *channels,
- uint16_t *rssi
+ u32 index,
+ u16 *numchannels,
+ u16 *channels,
+ u16 *rssi
);
/**
- * fmd_rx_step_frequency() - Steps one channel up or down.
- * @context: Pointer to FM Driver Context
- * @upwards: IF true step upwards else downwards.
+ * fmd_rx_block_scan() - Starts Block Scan.
+ * Starts block scan for retriving the RSSI level of channels
+ * in the given block.
+ * @context: FM Driver Context
+ * @start_freq: Starting frequency of the block from where scanning has
+ * to be started.
+ * @stop_freq: End frequency of the block to be scanned.
+ * @antenna: Antenna to be used during scanning.
* Returns:
- * FMD_RESULT_WAIT, if step frequency started successfully.
+ * FMD_RESULT_ONGOING, if scan band started successfully.
+ * FMD_RESULT_PARAMETER_INVALID, if parameters are invalid.
* FMD_RESULT_IO_ERROR, if there is an error.
* FMD_RESULT_BUSY, if FM Driver is not in idle state.
* FMD_RESULT_RESPONSE_WRONG, if wrong response received from chip.
*/
-uint8_t fmd_rx_step_frequency(
- void *context,
- bool upwards
+u8 fmd_rx_block_scan(
+ void *context,
+ u32 start_freq,
+ u32 stop_freq,
+ u8 antenna
);
/**
- * fmd_rx_get_rds() - Gets the current status of RDS transmission.
- * @context: Pointer to FM Driver Context
- * @on: pointer to RDS status
- * Returns:
- * FMD_RESULT_SUCCESS, if no error.
- * FMD_RESULT_IO_ERROR, if there is an error.
- * FMD_RESULT_BUSY, if FM Driver is not in idle state.
+ * fmd_rx_get_block_scan_result() - Retrieves RSSI Level of channels.
+ * Retrieves the RSSI level of the channels in the block.
+ * @context: FM Driver Context
+ * @index: (out) Index value to retrieve the channels.
+ * @numchannels: (out) Number of channels found during Band Scan.
+ * @rssi: (out) Rssi of channels found during Band scan.
+ * Returns:
+ * FMD_RESULT_ONGOING, if no error.
+ * FMD_RESULT_IO_ERROR, if there is an error.
+ * FMD_RESULT_RESPONSE_WRONG, if wrong response received from chip.
*/
-uint8_t fmd_rx_get_rds(
- void *context,
- bool *on
+u8 fmd_rx_get_block_scan_result(
+ void *context,
+ u32 index,
+ u16 *numchannels,
+ u16 *rssi
);
/**
- * fmd_rx_query_rds_signal() - Gets information about the transmitter.
- * @context: Pointer to FM Driver Context
- * @is_signal:TX RDS signal
+ * fmd_rx_get_rds() - Gets the current status of RDS transmission.
+ * @context: FM Driver Context
+ * @on: (out) RDS status
* Returns:
* FMD_RESULT_SUCCESS, if no error.
* FMD_RESULT_IO_ERROR, if there is an error.
* FMD_RESULT_BUSY, if FM Driver is not in idle state.
- * FMD_RESULT_RESPONSE_WRONG, if wrong response received from chip.
*/
-uint8_t fmd_rx_query_rds_signal(
+u8 fmd_rx_get_rds(
void *context,
- bool *is_signal
+ bool *on
);
/**
* fmd_rx_buffer_set_size() - Sets the number of groups that the data buffer.
* can contain and clears the buffer.
- * @context: Pointer to FM Driver Context
+ * @context: FM Driver Context
* @size: buffer size
* Returns:
* FMD_RESULT_SUCCESS, if no error.
@@ -780,16 +880,16 @@ uint8_t fmd_rx_query_rds_signal(
* FMD_RESULT_BUSY, if FM Driver is not in idle state.
* FMD_RESULT_RESPONSE_WRONG, if wrong response received from chip.
*/
-uint8_t fmd_rx_buffer_set_size(
+u8 fmd_rx_buffer_set_size(
void *context,
- uint8_t size
+ u8 size
);
/**
- * fmd_rx_buffer_set_threshold() - Sets the group number at which the buffer.
- * full interrupt must be generated.
- * The interrupt will be set after reception of the group.
- * @context: Pointer to FM Driver Context
+ * fmd_rx_buffer_set_threshold() - RDS Buffer Threshold level in FM Chip.
+ * Sets the group number at which the RDS buffer full interrupt must be
+ * generated. The interrupt will be set after reception of the group.
+ * @context: FM Driver Context
* @threshold: threshold level.
* Returns:
* FMD_RESULT_SUCCESS, if no error.
@@ -797,229 +897,436 @@ uint8_t fmd_rx_buffer_set_size(
* FMD_RESULT_BUSY, if FM Driver is not in idle state.
* FMD_RESULT_RESPONSE_WRONG, if wrong response received from chip.
*/
-uint8_t fmd_rx_buffer_set_threshold(
+u8 fmd_rx_buffer_set_threshold(
void *context,
- uint8_t threshold
+ u8 threshold
);
/**
- * fmd_rx_set_ctrl() - Enables or disables demodulation of RDS data.
- * @context: Pointer to FM Driver Context
- * @onoffState : Rx Set ON /OFF control
+ * fmd_rx_set_rds() - Enables or disables demodulation of RDS data.
+ * @context: FM Driver Context
+ * @on_off_state : Rx Set ON /OFF control
* Returns:
* FMD_RESULT_SUCCESS, if no error.
* FMD_RESULT_IO_ERROR, if there is an error.
* FMD_RESULT_BUSY, if FM Driver is not in idle state.
* FMD_RESULT_RESPONSE_WRONG, if wrong response received from chip.
*/
-uint8_t fmd_rx_set_ctrl(
+u8 fmd_rx_set_rds(
void *context,
- uint8_t onoffState
+ u8 on_off_state
);
/**
* fmd_rx_get_low_level_rds_groups() - Gets Low level RDS group data.
- * @context: Pointer to FM Driver Context
+ * @context: FM Driver Context
* @index: RDS group index
* @rds_buf_count: Count for RDS buffer
- * @block1: RDS Block 1
- * @block2: RDS Block 2
- * @block3: RDS Block 3
- * @block4: RDS Block 4
- * @status1: RDS data status 1
- * @status2: RDS data status 2
- * @status3: RDS data status 3
- * @status4: RDS data status 4
+ * @block1: (out) RDS Block 1
+ * @block2: (out) RDS Block 2
+ * @block3: (out) RDS Block 3
+ * @block4: (out) RDS Block 4
+ * @status1: (out) RDS data status 1
+ * @status2: (out) RDS data status 2
+ * @status3: (out) RDS data status 3
+ * @status4: (out) RDS data status 4
* Returns:
* FMD_RESULT_SUCCESS, if no error.
* FMD_RESULT_IO_ERROR, if there is an error.
* FMD_RESULT_BUSY, if FM Driver is not in idle state.
*/
-uint8_t fmd_rx_get_low_level_rds_groups(
+u8 fmd_rx_get_low_level_rds_groups(
+ void *context,
+ u8 index,
+ u8 *rds_buf_count,
+ u16 *block1,
+ u16 *block2,
+ u16 *block3,
+ u16 *block4,
+ u8 *status1,
+ u8 *status2,
+ u8 *status3,
+ u8 *status4
+ );
+
+/**
+ * fmd_tx_set_pa() - Enables or disables the Power Amplifier.
+ * @context: FM Driver Context
+ * @on: Power Amplifier current state to set
+ * Returns:
+ * FMD_RESULT_SUCCESS, if set Power Amplifier done successfully.
+ * FMD_RESULT_IO_ERROR, if there is an error.
+ * FMD_RESULT_BUSY, if FM Driver is not in idle state.
+ * FMD_RESULT_RESPONSE_WRONG, if wrong response received from chip.
+ */
+u8 fmd_tx_set_pa(
+ void *context,
+ bool on
+ );
+
+/**
+ * fmd_tx_set_signal_strength() - Sets the RF-level of the output FM signal.
+ * @context: FM Driver Context
+ * @strength: Signal strength to be set for FM Tx in dBuV.
+ * Returns:
+ * FMD_RESULT_SUCCESS, if set RSSI Level done successfully.
+ * FMD_RESULT_IO_ERROR, if there is an error.
+ * FMD_RESULT_PARAMETER_INVALID, if parameter is invalid.
+ * FMD_RESULT_BUSY, if FM Driver is not in idle state.
+ * FMD_RESULT_RESPONSE_WRONG, if wrong response received from chip.
+ */
+u8 fmd_tx_set_signal_strength(
void *context,
- uint8_t index,
- uint8_t *rds_buf_count,
- uint16_t *block1,
- uint16_t *block2,
- uint16_t *block3,
- uint16_t *block4,
- uint8_t *status1,
- uint8_t *status2,
- uint8_t *status3,
- uint8_t *status4
- );
-
-/**
- * fmd_set_audio_dac() - Enables or disables the audio DAC.
- * @context: Pointer to FM Driver Context
- * @dac_state: DAC state
+ u16 strength
+ );
+
+/**
+ * fmd_tx_get_signal_strength() - Retrieves current RSSI of FM Tx.
+ * @context: FM Driver Context
+ * @strength: (out) Strength of signal being transmitted in dBuV.
+ * Returns:
+ * FMD_RESULT_SUCCESS, if no error.
+ * FMD_RESULT_IO_ERROR, if there is an error.
+ * FMD_RESULT_BUSY, if FM Driver is not in idle state.
+ */
+u8 fmd_tx_get_signal_strength(
+ void *context,
+ u16 *strength
+ );
+
+/**
+ * fmd_tx_set_freq_range() - Sets the FM band and specifies the custom band.
+ * @context: FM Driver Context
+ * @range: Freq range to set on FM Tx.
* Returns:
* FMD_RESULT_SUCCESS, if no error.
+ * FMD_RESULT_PARAMETER_INVALID, if parameter is invalid.
* FMD_RESULT_IO_ERROR, if there is an error.
* FMD_RESULT_BUSY, if FM Driver is not in idle state.
* FMD_RESULT_RESPONSE_WRONG, if wrong response received from chip.
*/
-uint8_t fmd_set_audio_dac(
+u8 fmd_tx_set_freq_range(
void *context,
- uint8_t dac_state
+ u8 range
);
/**
- * fmd_set_volume() - Sets the receive audio volume.
- * @context: Pointer to FM Driver Context
- * @volume: Audio volume level
+ * fmd_tx_get_freq_range() - Gets the FM band currently in use.
+ * @context: FM Driver Context
+ * @range: (out) Frequency Range set on Fm Tx.
* Returns:
* FMD_RESULT_SUCCESS, if no error.
* FMD_RESULT_IO_ERROR, if there is an error.
* FMD_RESULT_BUSY, if FM Driver is not in idle state.
+ */
+u8 fmd_tx_get_freq_range(
+ void *context,
+ u8 *range
+ );
+
+/**
+ * fmd_tx_set_grid() - Sets the tuning grid size.
+ * @context: FM Driver Context
+ * @grid: FM Grid (50 Khz, 100 Khz, 200 Khz) to be set for FM Tx.
+ * Returns:
+ * FMD_RESULT_SUCCESS, if no error.
+ * FMD_RESULT_PARAMETER_INVALID, if parameter is invalid.
+ * FMD_RESULT_IO_ERROR, if there is an error.
+ * FMD_RESULT_BUSY, if FM Driver is not in idle state.
* FMD_RESULT_RESPONSE_WRONG, if wrong response received from chip.
*/
-uint8_t fmd_set_volume(
+u8 fmd_tx_set_grid(
void *context,
- uint8_t volume
+ u8 grid
);
/**
- * fmd_get_volume() - Retrives the current audio volume.
- * @context: Pointer to FM Driver Context
- * @volume: Pointer to base type Volume
+ * fmd_tx_get_grid() - Gets the current tuning grid size.
+ * @context: FM Driver Context
+ * @grid: (out) FM Grid (50 Khz, 100 Khz, 200 Khz) currently set on FM Tx.
* Returns:
* FMD_RESULT_SUCCESS, if no error.
* FMD_RESULT_IO_ERROR, if there is an error.
* FMD_RESULT_BUSY, if FM Driver is not in idle state.
*/
-uint8_t fmd_get_volume(
+u8 fmd_tx_get_grid(
void *context,
- uint8_t *volume
+ u8 *grid
);
/**
- * fmd_set_balance() - Controls the receiver audio balance.
- * @context: Pointer to FM Driver Context
- * @balance: Audiio balance level
+ * fmd_tx_set_preemphasis() - Sets the Preemphasis characteristic of the Tx.
+ * @context: FM Driver Context
+ * @preemphasis: Pre-emphasis level to be set for FM Tx.
+ * Returns:
+ * FMD_RESULT_SUCCESS, if no error.
+ * FMD_RESULT_IO_ERROR, if there is an error.
+ * FMD_RESULT_RESPONSE_WRONG, if wrong response received from chip.
+ */
+u8 fmd_tx_set_preemphasis(
+ void *context,
+ u8 preemphasis
+ );
+
+/**
+ * fmd_tx_get_preemphasis() - Gets the currently used Preemphasis char of th FM Tx.
+ * @context: FM Driver Context.
+ * @preemphasis: (out) Preemphasis Level used for FM Tx.
* Returns:
* FMD_RESULT_SUCCESS, if no error.
* FMD_RESULT_IO_ERROR, if there is an error.
* FMD_RESULT_BUSY, if FM Driver is not in idle state.
+ */
+u8 fmd_tx_get_preemphasis(
+ void *context,
+ u8 *preemphasis
+ );
+
+/**
+ * fmd_tx_set_frequency() - Sets the FM Channel for Tx.
+ * @context: FM Driver Context
+ * @freq: Freq to be set for transmission.
+ * Returns:
+ * FMD_RESULT_SUCCESS, if set frequency done successfully.
+ * FMD_RESULT_IO_ERROR, if there is an error.
+ * FMD_RESULT_BUSY, if FM Driver is not in idle state.
* FMD_RESULT_RESPONSE_WRONG, if wrong response received from chip.
*/
-uint8_t fmd_set_balance(
+u8 fmd_tx_set_frequency(
void *context,
- int8_t balance
+ u32 freq
);
/**
- * fmd_get_balance() - Retrives the receiver current audio balance level.
- * @context: Pointer to FM Driver Context
- * @balance: Pointer to Audio balance level
+ * fmd_rx_get_frequency() - Gets the currently used Channel for Tx.
+ * @context: FM Driver Context
+ * @freq: (out) Frequency set on FM Tx.
* Returns:
* FMD_RESULT_SUCCESS, if no error.
* FMD_RESULT_IO_ERROR, if there is an error.
* FMD_RESULT_BUSY, if FM Driver is not in idle state.
+ * FMD_RESULT_RESPONSE_WRONG, if wrong response received from chip.
*/
-uint8_t fmd_get_balance(
+u8 fmd_tx_get_frequency(
void *context,
- int8_t *balance
+ u32 *freq
);
/**
- * fmd_set_mute() - Enables or disables muting of the analog audio(DAC).
- * @context: Pointer to FM Driver Context
- * @mute_on: bool of mute on
+ * fmd_tx_enable_stereo_mode() - Sets Stereo mode state for TX.
+ * @context: FM Driver Context
+ * @enable_stereo_mode: Flag indicating enabling or disabling Stereo mode.
* Returns:
- * FMD_RESULT_WAIT, if no error.
+ * FMD_RESULT_SUCCESS, if no error.
* FMD_RESULT_IO_ERROR, if there is an error.
* FMD_RESULT_BUSY, if FM Driver is not in idle state.
* FMD_RESULT_RESPONSE_WRONG, if wrong response received from chip.
*/
-uint8_t fmd_set_mute(
+u8 fmd_tx_enable_stereo_mode(
void *context,
- bool mute_on
+ bool enable_stereo_mode
+ );
+
+/**
+ * fmd_tx_get_stereo_mode() - Gets the currently used FM Tx stereo mode.
+ * @context: FM Driver Context
+ * @stereo_mode: (out) Stereo Mode state set on FM Tx.
+ * Returns:
+ * FMD_RESULT_SUCCESS, if no error.
+ * FMD_RESULT_IO_ERROR, if there is an error.
+ * FMD_RESULT_BUSY, if FM Driver is not in idle state.
+ */
+u8 fmd_tx_get_stereo_mode(
+ void *context,
+ bool *stereo_mode
+ );
+
+/**
+ * fmd_tx_set_pilot_deviation() - Sets pilot deviation in HZ
+ * @context: FM Driver Context
+ * @deviation: Pilot deviation in HZ to set on FM Tx.
+ * Returns:
+ * FMD_RESULT_SUCCESS, if no error.
+ * FMD_RESULT_IO_ERROR, if there is an error.
+ * FMD_RESULT_RESPONSE_WRONG, if wrong response received from chip.
+ */
+u8 fmd_tx_set_pilot_deviation(
+ void *context,
+ u16 deviation
+ );
+
+/**
+ * fmd_tx_get_pilot_deviation() - Retrieves the current pilot deviation.
+ * @context: FM Driver Context
+ * @deviation: (out) Pilot deviation set on FM Tx.
+ * Returns:
+ * FMD_RESULT_SUCCESS, if no error.
+ * FMD_RESULT_IO_ERROR, if there is an error.
+ * FMD_RESULT_BUSY, if FM Driver is not in idle state.
+ */
+u8 fmd_tx_get_pilot_deviation(
+ void *context,
+ u16 *deviation
);
/**
- * fmd_get_mute() - Retrives the current state of analog audio(DAC).
- * @context: Pointer to FM Driver Context
- * @mute_on: Pointer to base type mute on
+ * fmd_tx_set_rds_deviation() - Sets Rds deviation in HZ.
+ * @context: FM Driver Context
+ * @deviation: RDS deviation in HZ.
* Returns:
* FMD_RESULT_SUCCESS, if no error.
* FMD_RESULT_IO_ERROR, if there is an error.
* FMD_RESULT_BUSY, if FM Driver is not in idle state.
+ * FMD_RESULT_RESPONSE_WRONG, if wrong response received from chip.
*/
-uint8_t fmd_get_mute(
+u8 fmd_tx_set_rds_deviation(
void *context,
- bool *mute_on
+ u16 deviation
);
/**
- * fmd_bt_set_ctrl() - Sets parameters of the BT Sample Rate Converter.
- * The sample rate conversion type(up or down) of the digital output
- * should be set to "up" if the required audio output rate exceeds
- * 41.3 kHz, otherwise the conversion type is down"
- * @context: Pointer to FM Driver Context
- * @up_conversion: Rate convertor -up
+ * fmd_tx_get_rds_deviation() - Retrieves the current Rds deviation.
+ * @context: FM Driver Context
+ * @deviation: (out) RDS deviation currently set.
+ * Returns:
+ * FMD_RESULT_SUCCESS, if no error.
+ * FMD_RESULT_IO_ERROR, if there is an error.
+ * FMD_RESULT_BUSY, if FM Driver is not in idle state.
+ */
+u8 fmd_tx_get_rds_deviation(
+ void *context,
+ u16 *deviation
+ );
+
+/**
+ * fmd_tx_set_rds() - Enables or disables RDS transmission for Tx.
+ * @context: FM Driver Context
+ * @on: Boolean - RDS ON
* Returns:
* FMD_RESULT_SUCCESS, if no error.
* FMD_RESULT_IO_ERROR, if there is an error.
* FMD_RESULT_BUSY, if FM Driver is not in idle state.
* FMD_RESULT_RESPONSE_WRONG, if wrong response received from chip.
*/
-uint8_t fmd_bt_set_ctrl(
+u8 fmd_tx_set_rds(
+ void *context,
+ bool on
+ );
+
+/**
+ * fmd_rx_get_rds() - Gets the current status of RDS transmission for FM Tx.
+ * @context: FM Driver Context
+ * @on: (out) Rds enabled or disabled.
+ * Returns:
+ * FMD_RESULT_SUCCESS, if no error.
+ * FMD_RESULT_IO_ERROR, if there is an error.
+ * FMD_RESULT_BUSY, if FM Driver is not in idle state.
+ */
+u8 fmd_tx_get_rds(
void *context,
- bool up_conversion
+ bool *on
);
/**
- * fmd_bt_set_mode() - Sets the output of the BT Sample Rate Converter.
- * @context: Pointer to FM Driver Context
- * @output: output mode
+ * fmd_tx_set_group() - Programs a grp on a certain position in the RDS buffer.
+ * @context: FM Driver Context
+ * @position: RDS group position
+ * @block1: Data to be transmitted in Block 1
+ * @block2: Data to be transmitted in Block 2
+ * @block3: Data to be transmitted in Block 3
+ * @block4: Data to be transmitted in Block 4
* Returns:
* FMD_RESULT_SUCCESS, if no error.
* FMD_RESULT_IO_ERROR, if there is an error.
* FMD_RESULT_BUSY, if FM Driver is not in idle state.
* FMD_RESULT_RESPONSE_WRONG, if wrong response received from chip.
*/
-uint8_t fmd_bt_set_mode(
+u8 fmd_tx_set_group(
void *context,
- uint8_t output
+ u16 position,
+ u8 block1[2],
+ u8 block2[2],
+ u8 block3[2],
+ u8 block4[2]
);
/**
- * fmd_ext_set_mode() - Sets the output mode of the Ext Sample Rate Converter.
- * @context: Pointer to FM Driver Context
- * @output: output mode
+ * fmd_tx_buffer_set_size() - Controls the size of the RDS buffer in groups.
+ * @context: FM Driver Context
+ * @buffer_size: RDS buffer size.
* Returns:
* FMD_RESULT_SUCCESS, if no error.
* FMD_RESULT_IO_ERROR, if there is an error.
* FMD_RESULT_BUSY, if FM Driver is not in idle state.
* FMD_RESULT_RESPONSE_WRONG, if wrong response received from chip.
*/
-uint8_t fmd_ext_set_mode(
+u8 fmd_tx_buffer_set_size(
void *context,
- uint8_t output
+ u16 buffer_size
);
/**
- * fmd_ext_set_ctrl() - Sets parameters of the Ext Sample Rate Converter.
- * The sample rate conversion type(up or down)
- * of the digital output should be set to "up" if the required audio
- * output rate exceeds 41.3 kHz, otherwise the conversion type is "down".
- * @context: Pointer to FM Driver Context
- * @up_conversion: boolean type-Upconversion for sample rate.
+ * fmd_set_volume() - Sets the receive audio volume.
+ * @context: FM Driver Context
+ * @volume: Audio volume level
* Returns:
* FMD_RESULT_SUCCESS, if no error.
* FMD_RESULT_IO_ERROR, if there is an error.
* FMD_RESULT_BUSY, if FM Driver is not in idle state.
* FMD_RESULT_RESPONSE_WRONG, if wrong response received from chip.
*/
-uint8_t fmd_ext_set_ctrl(
+u8 fmd_set_volume(
void *context,
- bool up_conversion
+ u8 volume
+ );
+
+/**
+ * fmd_get_volume() - Retrives the current audio volume.
+ * @context: FM Driver Context
+ * @volume: Analog Volume level.
+ * Returns:
+ * FMD_RESULT_SUCCESS, if no error.
+ * FMD_RESULT_IO_ERROR, if there is an error.
+ * FMD_RESULT_BUSY, if FM Driver is not in idle state.
+ */
+u8 fmd_get_volume(
+ void *context,
+ u8 *volume
+ );
+
+/**
+ * fmd_set_balance() - Controls the receiver audio balance.
+ * @context: FM Driver Context
+ * @balance: Audio balance level
+ * Returns:
+ * FMD_RESULT_SUCCESS, if no error.
+ * FMD_RESULT_IO_ERROR, if there is an error.
+ * FMD_RESULT_BUSY, if FM Driver is not in idle state.
+ * FMD_RESULT_RESPONSE_WRONG, if wrong response received from chip.
+ */
+u8 fmd_set_balance(
+ void *context,
+ s8 balance
+ );
+
+/**
+ * fmd_set_mute() - Enables or disables muting of the analog audio(DAC).
+ * @context: FM Driver Context
+ * @mute_on: bool of mute on
+ * Returns:
+ * FMD_RESULT_SUCCESS, if mute done successfully.
+ * FMD_RESULT_IO_ERROR, if there is an error.
+ * FMD_RESULT_BUSY, if FM Driver is not in idle state.
+ * FMD_RESULT_RESPONSE_WRONG, if wrong response received from chip.
+ */
+u8 fmd_set_mute(
+ void *context,
+ bool mute_on
);
/**
* fmd_ext_set_mute() - Enables or disables muting of the audio channel.
- * @context: Pointer to FM Driver Context
+ * @context: FM Driver Context
* @mute_on: bool to Mute
* Returns:
* FMD_RESULT_SUCCESS, if no error.
@@ -1027,50 +1334,50 @@ uint8_t fmd_ext_set_ctrl(
* FMD_RESULT_BUSY, if FM Driver is not in idle state.
* FMD_RESULT_RESPONSE_WRONG, if wrong response received from chip.
*/
-uint8_t fmd_ext_set_mute(
+u8 fmd_ext_set_mute(
void *context,
bool mute_on
);
/**
* fmd_power_up() - Puts the system in Powerup state.
- * @context: Pointer to FM Driver Context
+ * @context: FM Driver Context
* Returns:
- * FMD_RESULT_WAIT, if power up command sent successfully to chip.
+ * FMD_RESULT_SUCCESS, if power up command sent successfully to chip.
* FMD_RESULT_IO_ERROR, if there is an error.
* FMD_RESULT_RESPONSE_WRONG, if wrong response received from chip.
*/
-uint8_t fmd_power_up(
+u8 fmd_power_up(
void *context
);
/**
* fmd_goto_standby() - Puts the system in standby mode.
- * @context: Pointer to FM Driver Context
+ * @context: FM Driver Context
* Returns:
* FMD_RESULT_SUCCESS, if no error.
* FMD_RESULT_IO_ERROR, if there is an error.
* FMD_RESULT_RESPONSE_WRONG, if wrong response received from chip.
*/
-uint8_t fmd_goto_standby(
+u8 fmd_goto_standby(
void *context
);
/**
* fmd_goto_power_down() - Puts the system in Powerdown mode.
- * @context: Pointer to FM Driver Context
+ * @context: FM Driver Context
* Returns:
* FMD_RESULT_SUCCESS, if no error.
* FMD_RESULT_IO_ERROR, if there is an error.
* FMD_RESULT_RESPONSE_WRONG, if wrong response received from chip.
*/
-uint8_t fmd_goto_power_down(
+u8 fmd_goto_power_down(
void *context
);
/**
* fmd_select_ref_clk() - Selects the FM reference clock.
- * @context: Pointer to FM Driver Context
+ * @context: FM Driver Context
* @ref_clk: Ref Clock.
* Returns:
* FMD_RESULT_SUCCESS, if no error.
@@ -1078,26 +1385,26 @@ uint8_t fmd_goto_power_down(
* FMD_RESULT_BUSY, if FM Driver is not in idle state.
* FMD_RESULT_RESPONSE_WRONG, if wrong response received from chip.
*/
-uint8_t fmd_select_ref_clk(
+u8 fmd_select_ref_clk(
void *context,
- uint16_t ref_clk
+ u16 ref_clk
);
/**
- * fmd_select_ref_clk_pll() - Selects the freq of Referece Clock.
+ * fmd_set_ref_clk_pll() - Sets the freq of Referece Clock.
* Sets frequency and offset correction properties of the external
* reference clock of the PLL
- * @context: Pointer to FM driver Lib.
- * @freq: PLL Frequency.
+ * @context: FM driver context.
+ * @freq: PLL Frequency/ 2 in kHz.
* Returns:
* FMD_RESULT_SUCCESS, if no error.
* FMD_RESULT_IO_ERROR, if there is an error.
* FMD_RESULT_BUSY, if FM Driver is not in idle state.
* FMD_RESULT_RESPONSE_WRONG, if wrong response received from chip.
*/
-uint8_t fmd_select_ref_clk_pll(
+u8 fmd_set_ref_clk_pll(
void *context,
- uint16_t freq
+ u16 freq
);
/**
@@ -1106,7 +1413,7 @@ uint8_t fmd_select_ref_clk_pll(
* 0, if operation completed successfully.
* 1, otherwise.
*/
-unsigned int fmd_send_fm_ip_enable(void);
+u8 fmd_send_fm_ip_enable(void);
/**
* fmd_send_fm_ip_disable()- Disables the FM IP.
@@ -1114,40 +1421,29 @@ unsigned int fmd_send_fm_ip_enable(void);
* 0, if operation completed successfully.
* 1, otherwise.
*/
-unsigned int fmd_send_fm_ip_disable(void);
-
-/**
- * fmd_send_fm_ip_reset() - Resets the FM IP.
- * Returns:
- * 0, if operation completed successfully.
- * 1, otherwise.
- */
-unsigned int fmd_send_fm_ip_reset(void);
+u8 fmd_send_fm_ip_disable(void);
/**
* fmd_send_fm_firmware() - Send the FM Firmware File to Device.
- * @fw_buffer: Pointer to the Firmware Array
- * @fw_size: Size of firmware to be downloaded
+ * @fw_buffer: Firmware to be downloaded.
+ * @fw_size: Size of firmware to be downloaded.
* Returns:
* 0, if operation completed successfully.
* 1, otherwise.
*/
-unsigned int fmd_send_fm_firmware(
- uint8_t *fw_buffer,
- uint16_t fw_size
+u8 fmd_send_fm_firmware(
+ u8 *fw_buffer,
+ u16 fw_size
);
/**
* fmd_receive_data() - Processes the FM data received from device.
* @packet_length: Length of received Data Packet
- * @packet_buffer: Pointer to the received Data packet
- * Returns:
- * 0, if operation completed successfully.
- * 1, otherwise.
+ * @packet_buffer: Received Data buffer.
*/
void fmd_receive_data(
- uint32_t packet_length,
- uint8_t *packet_buffer
+ u16 packet_length,
+ u8 *packet_buffer
);
/**
@@ -1160,13 +1456,21 @@ void fmd_int_bufferfull(void);
/**
* fmd_hexdump() - Displays the HCI Data Bytes exchanged with FM Chip.
* @prompt: Prompt signifying the direction '<' for Rx '>' for Tx
- * @buffer: Pointer to the buffer to be displayed.
+ * @buffer: Buffer to be displayed.
* @num_bytes: Number of bytes of the buffer.
*/
void fmd_hexdump(
char prompt,
- uint8_t *buffer,
+ u8 *buffer,
int num_bytes
);
+/**
+ * fmd_isr() - FM Interrupt Service Routine.
+ * This function processes the Interrupt received from chip and performs the
+ * necessary action.
+ */
+void fmd_isr(void);
+
+
#endif /* _FMDRIVER_H_ */
diff --git a/drivers/media/radio/CG2900/platformosapi.c b/drivers/media/radio/CG2900/platformosapi.c
index ed814efef78..622592f302b 100755
--- a/drivers/media/radio/CG2900/platformosapi.c
+++ b/drivers/media/radio/CG2900/platformosapi.c
@@ -1,6 +1,4 @@
/*
- * file platformosapi.c
- *
* Copyright (C) ST-Ericsson SA 2010
*
* Linux Platform and OS Dependent File for FM Driver
@@ -23,16 +21,12 @@
#include <linux/skbuff.h>
/* ------------------ Internal function declarations ---------------------- */
-static void ste_fm_read_cb(
- struct ste_conn_device *dev,
- struct sk_buff *skb
- );
-static void ste_fm_reset_cb(
- struct ste_conn_device *dev
- );
-static int ste_fm_rds_thread(
- void *data
- );
+static void ste_fm_read_cb(struct ste_conn_device *dev, struct sk_buff *skb);
+static void ste_fm_reset_cb(struct ste_conn_device *dev);
+static int ste_fm_rds_thread(void *data);
+static void os_start_irq_thread(void);
+static void os_stop_irq_thread(void);
+static int ste_fm_irq_thread(void *data);
/*
* struct ste_fm_cb - Specifies callback structure for ste_conn user.
@@ -46,14 +40,18 @@ static struct ste_conn_callbacks ste_fm_cb = {
.read_cb = ste_fm_read_cb,
.reset_cb = ste_fm_reset_cb
};
+
static struct semaphore cmd_sem;
static struct semaphore hal_sem;
static struct semaphore read_rsp_sem;
static struct semaphore rds_sem;
-static struct task_struct *rds_thread_task;
+static struct semaphore interrupt_sem;
+static struct task_struct *rds_thread_task;
+static struct task_struct *irq_thread_task;
static struct ste_conn_device *ste_fm_cmd_evt;
-static struct mutex write_mutex;
-static struct mutex read_mutex;
+static struct mutex write_mutex;
+static struct mutex read_mutex;
+static spinlock_t fm_spinlock;
/* Debug Level */
/* 1: Only Error Logs */
@@ -65,6 +63,7 @@ EXPORT_SYMBOL(ste_fm_debug_level);
static ste_fm_rds_cb cb_rds_func;
static bool rds_thread_required;
+static bool irq_thread_required;
/* ------------------ Internal function definitions ---------------------- */
/**
@@ -73,26 +72,15 @@ static bool rds_thread_required;
* @dev: Device receiving data.
* @skb: Buffer with data coming form device.
*/
-static void ste_fm_read_cb(
- struct ste_conn_device *dev,
- struct sk_buff *skb
- )
+static void ste_fm_read_cb(struct ste_conn_device *dev, struct sk_buff *skb)
{
mutex_lock(&read_mutex);
FM_DEBUG_REPORT("ste_fm_read_cb");
if (skb->data != NULL && skb->len != 0) {
if (ste_fm_debug_level > 3)
- fmd_hexdump('<', skb->data, skb->len);
- if (skb->data[1] == 0x00 && \
- skb->data[2] == CATENA_OPCODE \
- && skb->data[3] == FM_WRITE) {
- /* Command Complete or RDS Data */
- fmd_receive_data(skb->data[0] - 3 , &skb->data[4]);
- } else if (skb->data[1] == CATENA_OPCODE \
- && skb->data[2] == FM_EVENT) {
- /* interrupt */
- fmd_receive_data(0 , &skb->data[3]);
- }
+ fmd_hexdump('<', skb->data, skb->len);
+ /* The first byte is length of bytes following */
+ fmd_receive_data(skb->data[0], &skb->data[1]);
}
kfree_skb(skb);
mutex_unlock(&read_mutex);
@@ -102,20 +90,16 @@ static void ste_fm_read_cb(
* ste_fm_reset_cb() - Reset callback fuction.
* @dev: CPD device reseting.
*/
-static void ste_fm_reset_cb(
- struct ste_conn_device *dev
- )
+static void ste_fm_reset_cb(struct ste_conn_device *dev)
{
FM_DEBUG_REPORT("ste_fm_reset_cb: Device Reset");
}
/**
* ste_fm_rds_thread() - Thread for receiving RDS data from Chip.
- * @data: Pointer to the data beng passed as paramter on starting the thread.
+ * @data: Data beng passed as paramter on starting the thread.
*/
-static int ste_fm_rds_thread(
- void *data
- )
+static int ste_fm_rds_thread(void *data)
{
FM_DEBUG_REPORT("ste_fm_rds_thread Created Successfully");
while (rds_thread_required) {
@@ -127,6 +111,47 @@ static int ste_fm_rds_thread(
return 0;
}
+/**
+ * os_start_irq_thread() - Function for starting Interrupt Thread.
+ */
+static void os_start_irq_thread(void)
+{
+ FM_DEBUG_REPORT("os_start_irq_thread");
+ irq_thread_task = kthread_create(ste_fm_irq_thread, NULL, "IrqThread");
+ if (IS_ERR(irq_thread_task)) {
+ FM_ERR_REPORT("os_start_irq_thread: "
+ "Unable to Create IRQThread");
+ irq_thread_task = NULL;
+ }
+ wake_up_process(irq_thread_task);
+}
+
+/**
+ * os_stop_irq_thread() - Function for stopping Interrupt Thread.
+ */
+static void os_stop_irq_thread(void)
+{
+ FM_DEBUG_REPORT("os_stop_irq_thread");
+ kthread_stop(irq_thread_task);
+ irq_thread_task = NULL;
+ FM_DEBUG_REPORT("-os_stop_irq_thread");
+}
+
+/**
+ * ste_fm_irq_thread() - Thread for processing Interrupts received from Chip.
+ * @data: Data beng passed as paramter on starting the thread.
+ */
+static int ste_fm_irq_thread(void *data)
+{
+ FM_DEBUG_REPORT("ste_fm_irq_thread Created Successfully");
+ while (irq_thread_required) {
+ fmd_isr();
+ os_sleep(100);
+ }
+ FM_DEBUG_REPORT("ste_fm_irq_thread Exiting!!!");
+ return 0;
+}
+
/* ------------------ External function definitions ---------------------- */
int os_fm_driver_init(void)
@@ -139,27 +164,31 @@ int os_fm_driver_init(void)
sema_init(&hal_sem, 1);
sema_init(&read_rsp_sem, 0);
sema_init(&rds_sem, 0);
+ sema_init(&interrupt_sem, 0);
- /* Create Mutex For Reading and Writing */
- mutex_init(&read_mutex);
- mutex_init(&write_mutex);
cb_rds_func = NULL;
rds_thread_required = STE_FALSE;
+ irq_thread_required = STE_TRUE;
ste_fm_cmd_evt = NULL;
+ /* Create Mutex For Reading and Writing */
+ mutex_init(&read_mutex);
+ mutex_init(&write_mutex);
+ spin_lock_init(&fm_spinlock);
+ os_start_irq_thread();
/* Register the FM Driver with
* Connectivity Protocol Driver */
- ste_fm_cmd_evt = ste_conn_register( \
- STE_CONN_DEVICES_FM_RADIO, &ste_fm_cb);
+ ste_fm_cmd_evt =
+ ste_conn_register(STE_CONN_DEVICES_FM_RADIO, &ste_fm_cb);
if (ste_fm_cmd_evt == NULL) {
- FM_ERR_REPORT("os_fm_driver_init: "\
- "Couldn't register STE_CONN_DEVICES_FM_RADIO to CPD."\
- "Either chip is not conected or Protocol Driver is not "
- "initialized");
+ FM_ERR_REPORT("os_fm_driver_init: "
+ "Couldn't register STE_CONN_DEVICES_FM_RADIO to "
+ "CPD. Either chip is not connected or "
+ "Protocol Driver is not initialized");
ret_val = 1;
} else {
- FM_INFO_REPORT("os_fm_driver_init: "\
- "Registered with CPD successfully!!!");
+ FM_INFO_REPORT("os_fm_driver_init: "
+ "Registered with CPD successfully!!!");
ret_val = 0;
}
FM_DEBUG_REPORT("os_fm_driver_init: Returning %d", ret_val);
@@ -169,64 +198,54 @@ int os_fm_driver_init(void)
void os_fm_driver_deinit(void)
{
FM_DEBUG_REPORT("os_fm_driver_deinit");
+ irq_thread_required = STE_FALSE;
mutex_destroy(&write_mutex);
mutex_destroy(&read_mutex);
+ os_stop_irq_thread();
/* Deregister the FM Driver with Connectivity Protocol Driver */
if (ste_fm_cmd_evt != NULL)
ste_conn_deregister(ste_fm_cmd_evt);
}
-void *os_mem_alloc(
- uint32_t num_bytes
- )
+void *os_mem_alloc(u32 num_bytes)
{
- void *p;
+ void *alloc_pointer;
FM_DEBUG_REPORT("os_mem_alloc for %d bytes", num_bytes);
- p = kmalloc(num_bytes, GFP_KERNEL);
- return p;
+ alloc_pointer = kmalloc(num_bytes, GFP_KERNEL);
+ return alloc_pointer;
}
-void os_mem_free(
- void *free_ptr
- )
+void os_mem_free(void *free_ptr)
{
FM_DEBUG_REPORT("os_mem_free");
if (NULL != free_ptr)
kfree(free_ptr);
}
-void os_mem_copy(
- void *dest,
- void *src,
- uint32_t num_bytes
- )
+void os_mem_copy(void *dest, void *src, u32 num_bytes)
{
FM_DEBUG_REPORT("os_mem_copy");
memcpy(dest, (const void *)src, num_bytes);
}
-void os_sleep(
- uint32_t milli_sec
- )
+void os_sleep(u32 milli_sec)
{
FM_DEBUG_REPORT("os_sleep");
schedule_timeout_interruptible(msecs_to_jiffies(milli_sec) + 1);
}
-void os_lock(void)
- __acquires(kernel_lock)
+void os_lock(void) __acquires(fm_spinlock)
{
FM_DEBUG_REPORT("os_lock");
- lock_kernel();
+ spin_lock(&fm_spinlock);
}
-void os_unlock(void)
- __releases(kernel_lock)
+void os_unlock(void) __releases(fm_spinlock)
{
FM_DEBUG_REPORT("os_unlock");
- unlock_kernel();
+ spin_unlock(&fm_spinlock);
}
void os_get_cmd_sem(void)
@@ -234,17 +253,19 @@ void os_get_cmd_sem(void)
int ret_val;
FM_DEBUG_REPORT("os_get_cmd_sem");
- ret_val = down_timeout(&cmd_sem, msecs_to_jiffies(500) + 1);
+
+ ret_val = down_timeout(&cmd_sem, msecs_to_jiffies(10000) + 1);
if (ret_val) {
- FM_ERR_REPORT("os_get_cmd_sem: down_timeout "\
- "returned error = %d", ret_val);
+ FM_ERR_REPORT("os_get_cmd_sem: down_timeout "
+ "returned error = %d", ret_val);
}
}
void os_set_cmd_sem(void)
{
FM_DEBUG_REPORT("os_set_cmd_sem");
+
up(&cmd_sem);
}
@@ -253,11 +274,11 @@ void os_get_hal_sem(void)
int ret_val;
FM_DEBUG_REPORT("os_get_hal_sem");
- ret_val = down_timeout(&hal_sem, msecs_to_jiffies(2000) + 1);
+ ret_val = down_timeout(&hal_sem, msecs_to_jiffies(500) + 1);
if (ret_val) {
- FM_ERR_REPORT("os_get_hal_sem: down_timeout "\
- "returned error = %d", ret_val);
+ FM_ERR_REPORT("os_get_hal_sem: down_timeout "
+ "returned error = %d", ret_val);
}
}
@@ -275,8 +296,8 @@ void os_get_read_response_sem(void)
ret_val = down_timeout(&read_rsp_sem, msecs_to_jiffies(500) + 1);
if (ret_val) {
- FM_ERR_REPORT("os_get_read_response_sem: "\
- "down_timeout returned error = %d", ret_val);
+ FM_ERR_REPORT("os_get_read_response_sem: "
+ "down_timeout returned error = %d", ret_val);
}
}
@@ -294,8 +315,8 @@ void os_get_rds_sem(void)
ret_val = down_killable(&rds_sem);
if (ret_val) {
- FM_ERR_REPORT("os_get_rds_sem: down_killable "\
- "returned error = %d", ret_val);
+ FM_ERR_REPORT("os_get_rds_sem: down_killable "
+ "returned error = %d", ret_val);
}
}
@@ -305,17 +326,35 @@ void os_set_rds_sem(void)
up(&rds_sem);
}
-void os_start_rds_thread(
- ste_fm_rds_cb cb_func
- )
+void os_get_interrupt_sem(void)
+{
+ int ret_val;
+
+ FM_DEBUG_REPORT("os_get_interrupt_sem");
+
+ ret_val = down_killable(&interrupt_sem);
+
+ if (ret_val) {
+ FM_ERR_REPORT("os_get_interrupt_sem: down_timeout "
+ "returned error = %d", ret_val);
+ }
+}
+
+void os_set_interrupt_sem(void)
+{
+ FM_DEBUG_REPORT("os_set_interrupt_sem");
+ up(&interrupt_sem);
+}
+
+void os_start_rds_thread(ste_fm_rds_cb cb_func)
{
FM_DEBUG_REPORT("os_start_rds_thread");
cb_rds_func = cb_func;
rds_thread_required = STE_TRUE;
rds_thread_task = kthread_create(ste_fm_rds_thread, NULL, "RdsThread");
if (IS_ERR(rds_thread_task)) {
- FM_ERR_REPORT("os_start_rds_thread: "\
- "Unable to Create RdsThread");
+ FM_ERR_REPORT("os_start_rds_thread: "
+ "Unable to Create RdsThread");
rds_thread_task = NULL;
}
wake_up_process(rds_thread_task);
@@ -324,7 +363,7 @@ void os_start_rds_thread(
void os_stop_rds_thread(void)
{
FM_DEBUG_REPORT("os_stop_rds_thread");
- /* In case threadis waiting, set the rds sem */
+ /* In case thread is waiting, set the rds sem */
os_set_rds_sem();
cb_rds_func = NULL;
rds_thread_required = STE_FALSE;
@@ -334,10 +373,7 @@ void os_stop_rds_thread(void)
}
}
-int ste_fm_send_packet(
- uint16_t num_bytes,
- uint8_t *send_buffer
- )
+int ste_fm_send_packet(u16 num_bytes, u8 *send_buffer)
{
int err = 0;
struct sk_buff *skb;
@@ -347,29 +383,30 @@ int ste_fm_send_packet(
if (ste_fm_debug_level > 3)
fmd_hexdump('>', send_buffer, num_bytes);
- /* Allocate 1 uint8_t less, since Protocol driver
- * appends the FM Channel */
+ /* Allocate 1 byte less, since Protocol driver
+ * appends the FM Logical Channel Byte */
skb = ste_conn_alloc_skb(num_bytes - 1, GFP_KERNEL);
if (skb) {
/* Copy the buffer removing the FM Header as this
* would be done by Protocol Driver */
- os_mem_copy(skb_put(skb, num_bytes - 1), \
- &send_buffer[1], num_bytes - 1);
+ os_mem_copy(skb_put(skb, num_bytes - 1),
+ &send_buffer[1], num_bytes - 1);
} else {
- FM_DEBUG_REPORT("Couldn't allocate sk_buff "\
+ FM_DEBUG_REPORT("Couldn't allocate sk_buff "
"with length %d", num_bytes - 1);
}
if (ste_fm_cmd_evt != NULL) {
err = ste_conn_write(ste_fm_cmd_evt, skb);
if (err) {
- FM_ERR_REPORT("ste_fm_send_packet: "\
- "Failed to send(%d) bytes using "\
- "ste_conn_write, err = %d",
- num_bytes - 1, err);
+ FM_ERR_REPORT("ste_fm_send_packet: "
+ "Failed to send(%d) bytes using "
+ "ste_conn_write, err = %d",
+ num_bytes - 1, err);
}
}
mutex_unlock(&write_mutex);
+ FM_DEBUG_REPORT("ste_fm_send_packet returning %d", err);
return err;
}
@@ -377,9 +414,6 @@ MODULE_AUTHOR("Hemant Gupta");
MODULE_LICENSE("GPL v2");
module_param(ste_fm_debug_level, ushort, S_IRUGO | S_IWUSR | S_IWGRP);
-MODULE_PARM_DESC(ste_fm_debug_level, "ste_fm_debug_level: "\
- " *1: Only Error Logs* "\
- " 2: Info Logs "\
- " 3: Debug Logs "\
- " 4: HCI Logs");
-
+MODULE_PARM_DESC(ste_fm_debug_level, "ste_fm_debug_level: "
+ " *1: Only Error Logs* "
+ " 2: Info Logs " " 3: Debug Logs " " 4: HCI Logs");
diff --git a/drivers/media/radio/CG2900/platformosapi.h b/drivers/media/radio/CG2900/platformosapi.h
index cccfb193cef..e677bf0d1a0 100755
--- a/drivers/media/radio/CG2900/platformosapi.h
+++ b/drivers/media/radio/CG2900/platformosapi.h
@@ -1,6 +1,4 @@
/*
- * file platformosapi.h
- *
* Copyright (C) ST-Ericsson SA 2010
*
* Linux Platform and OS Dependent File for FM Driver
@@ -16,8 +14,6 @@
#include <linux/module.h> /* Modules */
#include <linux/init.h> /* Initdata */
#include <linux/uaccess.h> /* copy to/from user */
-#include <linux/videodev2.h> /* v4l2 radio structs */
-#include <media/v4l2-common.h> /* v4l2 common structs */
#include <linux/smp_lock.h> /* Lock & Unlock Kernel */
#include <linux/semaphore.h> /* Semaphores */
#include <linux/version.h> /* for KERNEL_VERSION MACRO */
@@ -63,6 +59,7 @@ int os_fm_driver_init(void);
*/
void os_fm_driver_deinit(void);
+
/**
* os_mem_alloc() - Allocates requested bytes to a pointer.
* @num_bytes: Number of bytes to be allocated.
@@ -71,7 +68,7 @@ void os_fm_driver_deinit(void);
* Pointer pointing to the memory allocated.
*/
void *os_mem_alloc(
- uint32_t num_bytes
+ u32 num_bytes
);
/**
@@ -84,17 +81,15 @@ void os_mem_free(
/**
* os_mem_copy() - Copy memory of fixed bytes from Source to Destination.
- * @dest: Pointer pointing to the memory location where the data has
- * to be copied.
- * @src: Pointer pointing to the memory location from where the data has
- * to be copied.
+ * @dest: Memory location where the data has to be copied.
+ * @src: Memory location from where the data hasto be copied.
* @num_bytes: Number of bytes to be copied from Source pointer to
* Destination pointer.
*/
void os_mem_copy(
void *dest,
void *src,
- uint32_t num_bytes
+ u32 num_bytes
);
/**
@@ -102,7 +97,7 @@ void os_mem_copy(
* @milli_sec: Time in ms to suspend the task
*/
void os_sleep(
- uint32_t milli_sec
+ u32 milli_sec
);
/**
@@ -166,6 +161,18 @@ void os_get_rds_sem(void);
void os_set_rds_sem(void);
/**
+ * os_get_interrupt_sem() - Block on Interrupt Semaphore.
+ * Till Interrupt is received, Interrupt Task is blocked.
+ */
+void os_get_interrupt_sem(void);
+
+/**
+ * os_set_interrupt_sem() - Unblock on Interrupt Semaphore.
+ * on receiving Interrupt, Interrupt Task is un-blocked.
+ */
+void os_set_interrupt_sem(void);
+
+/**
* os_start_rds_thread() - Starts the RDS Thread for receiving RDS Data.
* This is started by Application when it wants to receive RDS Data.
* @cb_func: Callback function for receiving RDS Data
@@ -175,7 +182,7 @@ void os_start_rds_thread(
);
/**
- * os_stop_rds_thread() - Stops the RDS Thread when Application doesnot
+ * os_stop_rds_thread() - Stops the RDS Thread when Application does not
* want to receive RDS.
*/
void os_stop_rds_thread(void);
@@ -184,15 +191,15 @@ void os_stop_rds_thread(void);
* ste_fm_send_packet() - Sends the FM HCI Packet to the STE Protocol Driver.
* @num_bytes: Number of bytes of Data to be sent including
* Channel Identifier (08)
- * @send_buffer: Pointer to Buffer containing the Data to be sent to Chip.
+ * @send_buffer: Buffer containing the Data to be sent to Chip.
*
* Returns:
* 0 if packet was sent successfully to STE Protocol Driver, otherwise the
* corresponding error.
*/
int ste_fm_send_packet(
- uint16_t num_bytes,
- uint8_t *send_buffer
+ u16 num_bytes,
+ u8 *send_buffer
);
#endif /* PLATFORM_OSAPI_H */
diff --git a/drivers/media/radio/CG2900/radio-CG2900.c b/drivers/media/radio/CG2900/radio-CG2900.c
index 990daca25cd..6eaa922b3f0 100755
--- a/drivers/media/radio/CG2900/radio-CG2900.c
+++ b/drivers/media/radio/CG2900/radio-CG2900.c
@@ -1,6 +1,4 @@
/*
- * file radio-CG2900.c
- *
* Copyright (C) ST-Ericsson SA 2010
*
* Linux Wrapper for V4l2 FM Driver for CG2900.
@@ -11,33 +9,75 @@
*/
#include "stefmapi.h"
-#include "platformosapi.h"
#include "fmdriver.h"
#include <string.h>
#include "videodev.h"
#include "v4l2-ioctl.h"
#include "wait.h"
#include <linux/init.h> /* Initdata */
+#include <linux/videodev2.h> /* v4l2 radio structs */
+#include <media/v4l2-common.h> /* v4l2 common structs */
+#include "platformosapi.h"
-#define RADIO_CG2900_VERSION KERNEL_VERSION(0, 1, 1)
-#define BANNER "ST-Ericsson FM Radio Card driver v0.1.1"
-
-#define FMR_SEEK_NONE 0
-#define FMR_SEEK_IN_PROGRESS 1
-
-#define FMR_SWITCH_OFF 0
-#define FMR_SWITCH_ON 1
-#define FMR_STANDBY 2
-
-#define STE_HRTZ_MULTIPLIER 1000000
+#define RADIO_CG2900_VERSION KERNEL_VERSION(1, 1, 0)
+#define BANNER "ST-Ericsson FM Radio Card driver v1.1.0"
-#define SEARCH_TIME_PER_CH_GRID 120
-#define MAX_SCAN_SEEK_TIME (SEARCH_TIME_PER_CH_GRID * 408)
+#define FMR_HRTZ_MULTIPLIER 1000000
+#define FMR_EU_US_LOW_FREQ_IN_KHZ 87.5
+#define FMR_EU_US_HIGH_FREQ_IN_KHZ 108
+#define FMR_JAPAN_LOW_FREQ_IN_KHZ 76
+#define FMR_JAPAN_HIGH_FREQ_IN_KHZ 90
+#define FMR_CHINA_LOW_FREQ_IN_KHZ 70
+#define FMR_CHINA_HIGH_FREQ_IN_KHZ 108
/* freq in Hz to V4l2 freq (units of 62.5Hz) */
-#define HZ_2_V4L2(X) (2*(X)/125)
+#define HZ_TO_V4L2(X) (2*(X)/125)
/* V4l2 freq (units of 62.5Hz) to freq in Hz */
-#define V4L2_2_HZ(X) (((X)*125)/(2))
+#define V4L2_TO_HZ(X) (((X)*125)/(2))
+
+/* ------------------ Internal function declarations ---------------------- */
+static int cg2900_open(struct file *file);
+static int cg2900_release(struct file *file);
+static ssize_t cg2900_read(struct file *file,
+ char __user *data, size_t count, loff_t *pos);
+static unsigned int cg2900_poll(struct file *file,
+ struct poll_table_struct *wait);
+static int vidioc_querycap(struct file *file,
+ void *priv, struct v4l2_capability *query_caps);
+static int vidioc_get_tuner(struct file *file,
+ void *priv, struct v4l2_tuner *tuner);
+static int vidioc_set_tuner(struct file *file,
+ void *priv, struct v4l2_tuner *tuner);
+static int vidioc_get_modulator(struct file *file,
+ void *priv, struct v4l2_modulator *modulator);
+static int vidioc_set_modulator(struct file *file,
+ void *priv, struct v4l2_modulator *modulator);
+static int vidioc_get_frequency(struct file *file,
+ void *priv, struct v4l2_frequency *freq);
+static int vidioc_set_frequency(struct file *file,
+ void *priv, struct v4l2_frequency *freq);
+static int vidioc_query_ctrl(struct file *file,
+ void *priv, struct v4l2_queryctrl *query_ctrl);
+static int vidioc_get_ctrl(struct file *file,
+ void *priv, struct v4l2_control *ctrl);
+static int vidioc_set_ctrl(struct file *file,
+ void *priv, struct v4l2_control *ctrl);
+static int vidioc_get_ext_ctrls(struct file *file,
+ void *priv, struct v4l2_ext_controls *ext_ctrl);
+static int vidioc_set_ext_ctrls(struct file *file,
+ void *priv, struct v4l2_ext_controls *ext_ctrl);
+static int vidioc_set_hw_freq_seek(struct file *file,
+ void *priv,
+ struct v4l2_hw_freq_seek *freq_seek);
+static int vidioc_get_audio(struct file *file,
+ void *priv, struct v4l2_audio *audio);
+static int vidioc_set_audio(struct file *file,
+ void *priv, struct v4l2_audio *audio);
+static int vidioc_get_input(struct file *filp, void *priv, unsigned int *input);
+static int vidioc_set_input(struct file *filp, void *priv, unsigned int input);
+static void cg2900_convert_err_to_v4l2(char status_byte, char *out_byte);
+static int __init cg2900_init(void);
+static void __exit cg2900_exit(void);
static u32 freq_low;
static u32 freq_high;
@@ -45,449 +85,609 @@ static u32 freq_high;
/**************************************************************************
* Module parameters
**************************************************************************/
-static int radio_nr;
+static int radio_nr = -1;
/* Grid (kHz) */
-/* 0: 200 kHz (USA) */
+/* 0: 50 kHz (China) */
/* 1: 100 kHz (Europe, Japan) */
-/* 2: 50 kHz (China) */
+/* 2: 200 kHz (USA) */
static int grid;
-/* Bottom of Band (MHz) */
+/* FM Band (MHz) */
/* 0: 87.5 - 108 MHz (USA, Europe)*/
-/* 1: 70 - 108 MHz (China wide band) */
-/* 2: 76 - 90 MHz (Japan) */
+/* 1: 76 - 90 MHz (Japan) */
+/* 2: 70 - 108 MHz (China wide band) */
static int band;
-static uint32_t search_freq ;
-static uint16_t no_of_scanfreq ;
-static uint32_t scanfreq_rssi_level[32];
-static uint32_t scanfreq[32];
-static int users;
+/* cg2900_poll_queue - Main Wait Queue for polling (Scan/seek) */
+static wait_queue_head_t cg2900_poll_queue;
-/* radio_cg2900_poll_queue - Main Wait Queue for polling (Scan/seek) */
-static DECLARE_WAIT_QUEUE_HEAD(radio_cg2900_poll_queue);
+/* cg2900_read_queue - Main Wait Queue for receiving RDS Data */
+static DECLARE_WAIT_QUEUE_HEAD(cg2900_read_queue);
-/* ------------------ Internal function declarations ---------------------- */
-static int radio_cg2900_open(
- struct file *file
- );
-static int radio_cg2900_release(
- struct file *file
- );
-static ssize_t radio_cg2900_read(
- struct file *file,
- char __user *data,
- size_t count,
- loff_t *pos
- );
-static unsigned int radio_cg2900_poll(
- struct file *file,
- struct poll_table_struct *wait
- );
-static int vidioc_querycap(
- struct file *file,
- void *priv,
- struct v4l2_capability *arg
- );
-static int vidioc_g_tuner(
- struct file *file,
- void *priv,
- struct v4l2_tuner *arg
- );
-static int vidioc_s_tuner(
- struct file *file,
- void *priv,
- struct v4l2_tuner *arg
- );
-static int vidioc_g_frequency(
- struct file *file,
- void *priv,
- struct v4l2_frequency *arg
- );
-static int vidioc_s_frequency(
- struct file *file,
- void *priv,
- struct v4l2_frequency *arg
- );
-static int vidioc_queryctrl(
- struct file *file,
- void *priv,
- struct v4l2_queryctrl *arg
- );
-static int vidioc_g_ctrl(
- struct file *file,
- void *priv,
- struct v4l2_control *arg
- );
-static int vidioc_s_ctrl(
- struct file *file,
- void *priv,
- struct v4l2_control *arg
- );
-static int vidioc_g_ext_ctrls(
- struct file *file,
- void *priv,
- struct v4l2_ext_controls *arg
- );
-static int vidioc_s_hw_freq_seek(
- struct file *file,
- void *priv,
- struct v4l2_hw_freq_seek *arg
- );
-static int vidioc_g_audio(
- struct file *file,
- void *priv,
- struct v4l2_audio *arg
- );
-static int vidioc_g_input(
- struct file *filp,
- void *priv,
- unsigned int *i);
-static int vidioc_s_input(
- struct file *filp,
- void *priv,
- unsigned int i);
-static int vidioc_s_audio(
- struct file *file,
- void *priv,
- struct v4l2_audio *a
- );
-static void radio_cg2900_convert_err_to_v4l2(
- char status_byte,
- char *out_byte
- );
-static int __init radio_cg2900_init(void);
-static void __exit radio_cg2900_deinit(void);
+/**
+ * enum fmd_gocmd_t - Seek status of FM Radio.
+ * @FMR_SEEK_NONE: No seek in progress.
+ * @FMR_SEEK_IN_PROGRESS: Seek is in progress.
+ * Seek status of FM Radio.
+ */
+enum fm_seek_status_t {
+ FMR_SEEK_NONE,
+ FMR_SEEK_IN_PROGRESS
+};
+
+/**
+ * enum fm_power_state_t - Power states of FM Radio.
+ * @FMR_SWITCH_OFF: FM Radio is switched off.
+ * @FMR_SWITCH_ON: FM Radio is switched on.
+ * @FMR_STANDBY: FM Radio in standby state.
+ * Power states of FM Radio.
+ */
+enum fm_power_state_t {
+ FMR_SWITCH_OFF,
+ FMR_SWITCH_ON,
+ FMR_STANDBY
+};
/**
- * struct radio_cg2900_device - Stores FM Device Info.
+ * struct cg2900_device_t - Stores FM Device Info.
* @v_state: state of FM Radio
- * @v_volume: Analog Volume Gain of FM Radio
- * @v_frequency: Frequency tuned on FM Radio in V4L2 Format
- * @v_signalstrength: RSSI Level of the currently tuned frequency.
* @v_muted: FM Radio Mute/Unmute status
* @v_seekstatus: seek status
- * @v_audiopath: Audio Balance
- * @v_rds_enabled: Rds eable/disable status
+ * @v_rx_rds_enabled: Rds enable/disable status for FM Rx
+ * @v_tx_rds_enabled: Rds enable/disable status for FM Tx
+ * @v_rx_stereo_status: Stereo Mode status for FM Rx
+ * @v_tx_stereo_status: Stereo Mode status for FM Tx
+ * @v_volume: Analog Volume Gain of FM Radio
* @v_rssi_threshold: rssi Thresold set on FM Radio
+ * @v_frequency: Frequency tuned on FM Radio in V4L2 Format
+ * @v_audiopath: Audio Balance
+ * @v_waitonreadqueue: Flag for waiting on read queue.
+ * @v_fm_mode: Enum for storing the current FM Mode.
*
*/
-struct radio_cg2900_device_s {
- u8 v_state;
- int v_volume;
- u32 v_frequency;
- u32 v_signalstrength;
- u8 v_muted;
- u8 v_seekstatus;
- u32 v_audiopath;
- u8 v_rds_enabled;
- u16 v_rssi_threshold;
-} radio_cg2900_device;
-
-/* Global Structure Pointer to store the maintain FM Driver device info */
-struct radio_cg2900_device_s *g_radio_cg2900_device = &radio_cg2900_device;
-
-/* Time structure for Max time for scanning and seeking */
-static struct timeval max_scan_seek_time = {
- .tv_sec = MAX_SCAN_SEEK_TIME,
- .tv_usec = 0
-};
+struct cg2900_device_t {
+ u8 v_state;
+ u8 v_muted;
+ u8 v_seekstatus;
+ bool v_rx_rds_enabled;
+ bool v_tx_rds_enabled;
+ bool v_rx_stereo_status;
+ bool v_tx_stereo_status;
+ int v_volume;
+ u16 v_rssi_threshold;
+ u32 v_frequency;
+ u32 v_audiopath;
+ bool v_waitonreadqueue;
+ enum ste_fm_mode_t v_fm_mode;
+} __attribute__ ((packed));
+
+/* Global Structure to store the maintain FM Driver device info */
+static struct cg2900_device_t cg2900_device;
/* V4l2 File Operation Structure */
-static const struct v4l2_file_operations radio_cg2900_fops = {
- .owner = THIS_MODULE,
- .open = radio_cg2900_open,
- .release = radio_cg2900_release,
- .read = radio_cg2900_read,
- .poll = radio_cg2900_poll,
- .ioctl = video_ioctl2,
+static const struct v4l2_file_operations cg2900_fops = {
+ .owner = THIS_MODULE,
+ .open = cg2900_open,
+ .release = cg2900_release,
+ .read = cg2900_read,
+ .poll = cg2900_poll,
+ .ioctl = video_ioctl2,
};
/* V4L2 IOCTL Operation Structure */
-static const struct v4l2_ioctl_ops radio_cg2900_ioctl_ops = {
- .vidioc_querycap = vidioc_querycap,
- .vidioc_g_tuner = vidioc_g_tuner,
- .vidioc_s_tuner = vidioc_s_tuner,
- .vidioc_g_frequency = vidioc_g_frequency,
- .vidioc_s_frequency = vidioc_s_frequency,
- .vidioc_queryctrl = vidioc_queryctrl,
- .vidioc_g_ctrl = vidioc_g_ctrl,
- .vidioc_s_ctrl = vidioc_s_ctrl,
- .vidioc_g_ext_ctrls = vidioc_g_ext_ctrls,
- .vidioc_s_hw_freq_seek = vidioc_s_hw_freq_seek,
- .vidioc_g_audio = vidioc_g_audio,
- .vidioc_s_audio = vidioc_s_audio,
- .vidioc_g_input = vidioc_g_input,
- .vidioc_s_input = vidioc_s_input,
+static const struct v4l2_ioctl_ops cg2900_ioctl_ops = {
+ .vidioc_querycap = vidioc_querycap,
+ .vidioc_g_tuner = vidioc_get_tuner,
+ .vidioc_s_tuner = vidioc_set_tuner,
+ .vidioc_g_modulator = vidioc_get_modulator,
+ .vidioc_s_modulator = vidioc_set_modulator,
+ .vidioc_g_frequency = vidioc_get_frequency,
+ .vidioc_s_frequency = vidioc_set_frequency,
+ .vidioc_queryctrl = vidioc_query_ctrl,
+ .vidioc_g_ctrl = vidioc_get_ctrl,
+ .vidioc_s_ctrl = vidioc_set_ctrl,
+ .vidioc_g_ext_ctrls = vidioc_get_ext_ctrls,
+ .vidioc_s_ext_ctrls = vidioc_set_ext_ctrls,
+ .vidioc_s_hw_freq_seek = vidioc_set_hw_freq_seek,
+ .vidioc_g_audio = vidioc_get_audio,
+ .vidioc_s_audio = vidioc_set_audio,
+ .vidioc_g_input = vidioc_get_input,
+ .vidioc_s_input = vidioc_set_input,
};
/* V4L2 Video Device Structure */
-static struct video_device radio_cg2900_video_device = {
- .name = "STE CG2900 FM Rx/Tx Radio",
- .vfl_type = VID_TYPE_TUNER | VID_TYPE_CAPTURE,
- .fops = &radio_cg2900_fops,
- .ioctl_ops = &radio_cg2900_ioctl_ops,
- .release = video_device_release_empty,
+static struct video_device cg2900_video_device = {
+ .name = "STE CG2900 FM Rx/Tx Radio",
+ .vfl_type = VID_TYPE_TUNER | VID_TYPE_CAPTURE,
+ .fops = &cg2900_fops,
+ .ioctl_ops = &cg2900_ioctl_ops,
+ .release = video_device_release_empty,
};
+static u16 no_of_scan_freq;
+static u16 no_of_block_scan_freq;
+static u32 scanfreq_rssi_level[MAX_CHANNELS_TO_SCAN];
+static u16 block_scan_rssi_level[MAX_CHANNELS_FOR_BLOCK_SCAN];
+static u32 scanfreq[MAX_CHANNELS_TO_SCAN];
+static int users;
+
/* ------------------ Internal Function definitions ---------------------- */
/**
* vidioc_querycap()- Query FM Driver Capabilities.
* This function is used to query the capabilities of the
* FM Driver. This function is called when the application issues the IOCTL
- * VIDIOC_QUERYCAP
+ * VIDIOC_QUERYCAP.
*
- * @file: Pointer to the file structure
- * @priv: Pointer to the previous data of file structure.
- * @arg: Pointer to the v4l2_capability structure.
+ * @file: File structure.
+ * @priv: Previous data of file structure.
+ * @query_caps: v4l2_capability structure.
*
* Returns: 0
*/
-static int vidioc_querycap(
- struct file *file,
- void *priv,
- struct v4l2_capability *arg
- )
+static int vidioc_querycap(struct file *file,
+ void *priv, struct v4l2_capability *query_caps)
{
- struct v4l2_capability *v = arg;
FM_DEBUG_REPORT("vidioc_querycap");
- memset(v, 0, sizeof(*v));
- strlcpy(v->driver, "CG2900 Driver", sizeof(v->driver));
- strlcpy(v->card, "CG2900 FM Radio", sizeof(v->card));
- strcpy(v->bus_info, "platform"); /* max. 32 bytes! */
- v->version = RADIO_CG2900_VERSION;
- v->capabilities = V4L2_CAP_TUNER |
- V4L2_CAP_RADIO |
- V4L2_CAP_READWRITE |
- V4L2_CAP_RDS_CAPTURE |
- V4L2_CAP_HW_FREQ_SEEK |
- V4L2_CAP_RDS_OUTPUT;
- memset(v->reserved, 0, sizeof(v->reserved));
+ memset(query_caps, 0, sizeof(*query_caps));
+ strlcpy(query_caps->driver,
+ "CG2900 Driver", sizeof(query_caps->driver));
+ strlcpy(query_caps->card, "CG2900 FM Radio", sizeof(query_caps->card));
+ strcpy(query_caps->bus_info, "platform");
+ query_caps->version = RADIO_CG2900_VERSION;
+ query_caps->capabilities = V4L2_CAP_TUNER |
+ V4L2_CAP_MODULATOR |
+ V4L2_CAP_RADIO |
+ V4L2_CAP_READWRITE |
+ V4L2_CAP_RDS_CAPTURE | V4L2_CAP_HW_FREQ_SEEK | V4L2_CAP_RDS_OUTPUT;
FM_DEBUG_REPORT("vidioc_querycap returning 0");
return 0;
}
/**
- * vidioc_g_tuner()- Get FM Tuner Features.
+ * vidioc_get_tuner()- Get FM Tuner Features.
* This function is used to get the tuner features.
* This function is called when the application issues the IOCTL
* VIDIOC_G_TUNER
*
- * @file: Pointer to the file structure
- * @priv: Pointer to the previous data of file structure.
- * @arg: Pointer to the v4l2_tuner structure.
+ * @file: File structure.
+ * @priv: Previous data of file structure.
+ * @tuner: v4l2_tuner structure.
*
* Returns:
* 0 when no error
* -EINVAL: otherwise
*/
-static int vidioc_g_tuner(
- struct file *file,
- void *priv,
- struct v4l2_tuner *arg
- )
+static int vidioc_get_tuner(struct file *file,
+ void *priv, struct v4l2_tuner *tuner)
{
- struct v4l2_tuner *v = arg;
- uint8_t status;
- uint32_t mode;
- uint16_t rssi;
- FM_DEBUG_REPORT("vidioc_g_tuner");
-
- if (v->index > 0)
+ u8 status = STE_STATUS_OK;
+ u8 mode;
+ bool rds_enabled;
+ u16 rssi;
+ FM_DEBUG_REPORT("vidioc_get_tuner");
+
+ if (tuner->index > 0) {
+ FM_ERR_REPORT("vidioc_get_tuner: Only 1 tuner supported");
return -EINVAL;
+ }
- strcpy(v->name, "CG2900 FM Receiver/Transmitter ");
- v->type = V4L2_TUNER_RADIO;
- v->rangelow = HZ_2_V4L2(freq_low);
- v->rangehigh = HZ_2_V4L2(freq_high);
- v->capability = \
- V4L2_TUNER_CAP_LOW /* Frequency steps = 1/16 kHz */
- | V4L2_TUNER_CAP_STEREO /* Can receive stereo */
- | V4L2_TUNER_CAP_RDS; /* Supports RDS Capture/Transmission */
- status = ste_fm_get_mode(&mode);
- FM_DEBUG_REPORT("vidioc_g_tuner: mode = %d, ", mode);
- if (STE_STATUS_OK == status) {
- switch (mode) {
- /* stereo */
- case 0:
- v->audmode = V4L2_TUNER_MODE_STEREO;
- v->rxsubchans = V4L2_TUNER_SUB_STEREO |
- V4L2_TUNER_SUB_RDS;
- break;
- /* mono */
- case 1:
- v->audmode = V4L2_TUNER_SUB_MONO;
- v->rxsubchans = V4L2_TUNER_SUB_STEREO |
- V4L2_TUNER_SUB_RDS;
- break;
- /* Switching or Blending, set mode as Stereo */
- default:
- v->rxsubchans = V4L2_TUNER_SUB_MONO;
- v->audmode = V4L2_TUNER_MODE_STEREO |
- V4L2_TUNER_SUB_RDS ;
+ memset(tuner, 0, sizeof(*tuner));
+ strcpy(tuner->name, "CG2900 FM Receiver");
+ tuner->type = V4L2_TUNER_RADIO;
+ tuner->rangelow = HZ_TO_V4L2(freq_low);
+ tuner->rangehigh = HZ_TO_V4L2(freq_high);
+ tuner->capability = V4L2_TUNER_CAP_LOW /* Frequency steps = 1/16 kHz */
+ | V4L2_TUNER_CAP_STEREO /* Can receive stereo */
+ | V4L2_TUNER_CAP_RDS; /* Supports RDS Capture */
+
+ if (cg2900_device.v_fm_mode == STE_FM_RX_MODE) {
+ status = ste_fm_get_mode(&mode);
+ FM_DEBUG_REPORT("vidioc_get_tuner: mode = %d, ", mode);
+ if (STE_STATUS_OK == status) {
+ switch (mode) {
+ case STE_MODE_STEREO:
+ tuner->audmode = V4L2_TUNER_MODE_STEREO;
+ tuner->rxsubchans = V4L2_TUNER_SUB_STEREO;
+ tuner->rxsubchans &= ~V4L2_TUNER_SUB_MONO;
+ break;
+ case STE_MODE_MONO:
+ default:
+ tuner->audmode = V4L2_TUNER_SUB_MONO;
+ tuner->rxsubchans = V4L2_TUNER_SUB_MONO;
+ tuner->rxsubchans &= ~V4L2_TUNER_SUB_STEREO;
+ break;
+ }
+ } else {
+ /* Get mode API failed, set mode to mono */
+ tuner->audmode = V4L2_TUNER_MODE_MONO;
+ tuner->rxsubchans = V4L2_TUNER_SUB_MONO;
+ tuner->rxsubchans &= ~V4L2_TUNER_SUB_STEREO;
+ }
+
+ status = ste_fm_get_rds_status(&rds_enabled);
+ if (STE_STATUS_OK == status) {
+ if (STE_TRUE == rds_enabled)
+ tuner->rxsubchans |= V4L2_TUNER_SUB_RDS;
+ else
+ tuner->rxsubchans &= ~V4L2_TUNER_SUB_RDS;
+ } else {
+ tuner->rxsubchans &= ~V4L2_TUNER_SUB_RDS;
}
} else {
- /* Get mode API failed, set mode to mono */
- v->audmode = V4L2_TUNER_MODE_MONO;
- v->rxsubchans = V4L2_TUNER_SUB_MONO |
- V4L2_TUNER_SUB_RDS;
+ tuner->audmode = V4L2_TUNER_SUB_MONO;
+ tuner->rxsubchans = V4L2_TUNER_SUB_MONO;
+ tuner->rxsubchans &= ~V4L2_TUNER_SUB_RDS;
}
- status = ste_fm_get_signal_strength(&rssi);
- if (STE_STATUS_OK == status) {
- v->signal = rssi;
- FM_DEBUG_REPORT("vidioc_g_tuner: rssi level = %d, "\
- "signal = 0x%04x", rssi, v->signal);
+ if (cg2900_device.v_fm_mode == STE_FM_RX_MODE) {
+ status = ste_fm_get_signal_strength(&rssi);
+ if (STE_STATUS_OK == status)
+ tuner->signal = rssi;
+ else
+ tuner->signal = 0;
} else {
- v->signal = 0;
+ tuner->signal = 0;
}
- memset(v->reserved, 0, sizeof(v->reserved));
- return 0;
+
+ if (STE_STATUS_OK == status)
+ return 0;
+ else
+ return -EINVAL;
}
/**
- * vidioc_s_tuner()- Set FM Tuner Features.
+ * vidioc_set_tuner()- Set FM Tuner Features.
* This function is used to set the tuner features.
+ * It also sets the default FM Rx settings.
* This function is called when the application issues the IOCTL
* VIDIOC_S_TUNER
*
- * @file: Pointer to the file structure
- * @priv: Pointer to the previous data of file structure.
- * @arg: Pointer to the v4l2_tuner structure.
+ * @file: File structure.
+ * @priv: Previous data of file structure.
+ * @tuner: v4l2_tuner structure.
*
* Returns:
* 0 when no error
* -EINVAL: otherwise
*/
-static int vidioc_s_tuner(
- struct file *file,
- void *priv,
- struct v4l2_tuner *arg
- )
+static int vidioc_set_tuner(struct file *file,
+ void *priv, struct v4l2_tuner *tuner)
{
- const struct v4l2_tuner *v = arg;
+ bool rds_status = STE_FALSE;
+ bool stereo_status = STE_FALSE;
+ u8 status = STE_STATUS_OK;
- FM_DEBUG_REPORT("vidioc_s_tuner");
- if (v->index != 0) {
- /* Sorry, only 1 tuner */
+ FM_DEBUG_REPORT("vidioc_set_tuner");
+ if (tuner->index != 0) {
+ FM_ERR_REPORT("vidioc_set_tuner: Only 1 tuner supported");
return -EINVAL;
}
- return 0;
+ if (cg2900_device.v_fm_mode != STE_FM_RX_MODE) {
+ /* FM Rx mode should be configured as earlier mode was not
+ * FM Rx*/
+ if (0 == band) {
+ freq_low = FMR_EU_US_LOW_FREQ_IN_KHZ *
+ FMR_HRTZ_MULTIPLIER;
+ freq_high = FMR_EU_US_HIGH_FREQ_IN_KHZ *
+ FMR_HRTZ_MULTIPLIER;
+ } else if (1 == band) {
+ freq_low = FMR_JAPAN_LOW_FREQ_IN_KHZ *
+ FMR_HRTZ_MULTIPLIER;
+ freq_high = FMR_JAPAN_HIGH_FREQ_IN_KHZ *
+ FMR_HRTZ_MULTIPLIER;
+ } else {
+ freq_low = FMR_CHINA_LOW_FREQ_IN_KHZ *
+ FMR_HRTZ_MULTIPLIER;
+ freq_high = FMR_CHINA_HIGH_FREQ_IN_KHZ *
+ FMR_HRTZ_MULTIPLIER;
+ }
+ cg2900_device.v_fm_mode = STE_FM_RX_MODE;
+ cg2900_device.v_rx_rds_enabled =
+ (tuner->rxsubchans & V4L2_TUNER_SUB_RDS) ?
+ STE_TRUE : STE_FALSE;
+ if (tuner->rxsubchans & V4L2_TUNER_SUB_STEREO)
+ stereo_status = STE_TRUE;
+ else if (tuner->rxsubchans & V4L2_TUNER_SUB_MONO)
+ stereo_status = STE_FALSE;
+ cg2900_device.v_rx_stereo_status = stereo_status;
+ ste_fm_set_rx_default_settings(freq_low,
+ band,
+ grid,
+ cg2900_device.v_rx_rds_enabled,
+ cg2900_device.
+ v_rx_stereo_status);
+ ste_fm_set_rssi_threshold(cg2900_device.v_rssi_threshold);
+ } else {
+ /* Mode was FM Rx only, change the RDS settings or stereo mode
+ * if they are changed by application */
+ rds_status = (tuner->rxsubchans & V4L2_TUNER_SUB_RDS) ?
+ STE_TRUE : STE_FALSE;
+ if (tuner->rxsubchans & V4L2_TUNER_SUB_STEREO)
+ stereo_status = STE_TRUE;
+ else if (tuner->rxsubchans & V4L2_TUNER_SUB_MONO)
+ stereo_status = STE_FALSE;
+ if (stereo_status != cg2900_device.v_rx_stereo_status) {
+ cg2900_device.v_rx_stereo_status = stereo_status;
+ if (STE_TRUE == stereo_status)
+ status =
+ ste_fm_set_mode(FMD_STEREOMODE_BLENDING);
+ else
+ status = ste_fm_set_mode(FMD_STEREOMODE_MONO);
+ }
+ if (rds_status != cg2900_device.v_rx_rds_enabled) {
+ cg2900_device.v_rx_rds_enabled = rds_status;
+ if (STE_TRUE == rds_status)
+ status = ste_fm_rds_on();
+ else
+ status = ste_fm_rds_off();
+ }
+ }
+
+ if (STE_STATUS_OK == status)
+ return 0;
+ else
+ return -EINVAL;
}
/**
- * vidioc_g_frequency()- Get the Current FM Frequnecy.
+ * vidioc_get_modulator()- Get FM Modulator Features.
+ * This function is used to get the modulator features.
+ * This function is called when the application issues the IOCTL
+ * VIDIOC_G_MODULATOR
+ *
+ * @file: File structure.
+ * @priv: Previous data of file structure.
+ * @modulator: v4l2_modulator structure.
+ *
+ * Returns:
+ * 0 when no error
+ * -EINVAL: otherwise
+ */
+static int vidioc_get_modulator(struct file *file,
+ void *priv, struct v4l2_modulator *modulator)
+{
+ u8 status = STE_STATUS_OK;
+ bool rds_enabled;
+ u8 mode;
+ FM_DEBUG_REPORT("vidioc_get_modulator");
+
+ if (modulator->index > 0) {
+ FM_ERR_REPORT("vidioc_get_modulator: Only 1 "
+ "modulator supported");
+ return -EINVAL;
+ }
+
+ memset(modulator, 0, sizeof(*modulator));
+ strcpy(modulator->name, "CG2900 FM Transmitter");
+ modulator->rangelow = freq_low;
+ modulator->rangehigh = freq_high;
+ modulator->capability = V4L2_TUNER_CAP_NORM /* Frequency steps =
+ 1/16 kHz */
+ | V4L2_TUNER_CAP_STEREO /* Can receive stereo */
+ | V4L2_TUNER_CAP_RDS; /* Supports RDS Capture */
+
+ if (cg2900_device.v_fm_mode == STE_FM_TX_MODE) {
+ status = ste_fm_get_mode(&mode);
+ FM_DEBUG_REPORT("vidioc_get_modulator: mode = %d", mode);
+ if (STE_STATUS_OK == status) {
+ switch (mode) {
+ /* stereo */
+ case 0:
+ modulator->txsubchans = V4L2_TUNER_SUB_STEREO;
+ break;
+ /* mono */
+ case 1:
+ modulator->txsubchans = V4L2_TUNER_SUB_MONO;
+ break;
+ /* Switching or Blending, set mode as Stereo */
+ default:
+ modulator->txsubchans = V4L2_TUNER_SUB_STEREO;
+ }
+ } else {
+ /* Get mode API failed, set mode to mono */
+ modulator->txsubchans = V4L2_TUNER_SUB_MONO;
+ }
+ status = ste_fm_get_rds_status(&rds_enabled);
+ if (STE_STATUS_OK == status) {
+ if (STE_TRUE == rds_enabled)
+ modulator->txsubchans |= V4L2_TUNER_SUB_RDS;
+ else
+ modulator->txsubchans &= ~V4L2_TUNER_SUB_RDS;
+ } else {
+ modulator->txsubchans &= ~V4L2_TUNER_SUB_RDS;
+ }
+ } else {
+ modulator->txsubchans = V4L2_TUNER_SUB_MONO;
+ modulator->txsubchans &= ~V4L2_TUNER_SUB_RDS;
+ }
+
+ if (STE_STATUS_OK == status)
+ return 0;
+ else
+ return -EINVAL;
+}
+
+/**
+ * vidioc_set_modulator()- Set FM Modulator Features.
+ * This function is used to set the Modulaotr features.
+ * It also sets the default FM Tx settings.
+ * This function is called when the application issues the IOCTL
+ * VIDIOC_S_MODULATOR
+ *
+ * @file: File structure.
+ * @priv: Previous data of file structure.
+ * @modulator: v4l2_modulator structure.
+ *
+ * Returns:
+ * 0 when no error
+ * -EINVAL: otherwise
+ */
+static int vidioc_set_modulator(struct file *file,
+ void *priv, struct v4l2_modulator *modulator)
+{
+ bool rds_status = STE_FALSE;
+ bool stereo_status = STE_FALSE;
+ u8 status = STE_STATUS_OK;
+
+ FM_DEBUG_REPORT("vidioc_set_modulator");
+ if (modulator->index != 0) {
+ FM_ERR_REPORT("vidioc_set_modulator: Only 1 "
+ "modulator supported");
+ return -EINVAL;
+ }
+
+ if (cg2900_device.v_fm_mode != STE_FM_TX_MODE) {
+ /* FM Tx mode should be configured as earlier mode was not
+ * FM Tx*/
+ if (0 == band) {
+ freq_low = FMR_EU_US_LOW_FREQ_IN_KHZ *
+ FMR_HRTZ_MULTIPLIER;
+ freq_high = FMR_EU_US_HIGH_FREQ_IN_KHZ *
+ FMR_HRTZ_MULTIPLIER;
+ } else if (1 == band) {
+ freq_low = FMR_JAPAN_LOW_FREQ_IN_KHZ *
+ FMR_HRTZ_MULTIPLIER;
+ freq_high = FMR_JAPAN_HIGH_FREQ_IN_KHZ *
+ FMR_HRTZ_MULTIPLIER;
+ } else {
+ freq_low = FMR_CHINA_LOW_FREQ_IN_KHZ *
+ FMR_HRTZ_MULTIPLIER;
+ freq_high = FMR_CHINA_HIGH_FREQ_IN_KHZ *
+ FMR_HRTZ_MULTIPLIER;
+ }
+ cg2900_device.v_fm_mode = STE_FM_TX_MODE;
+ cg2900_device.v_rx_rds_enabled = STE_FALSE;
+ cg2900_device.v_tx_rds_enabled =
+ (modulator->txsubchans & V4L2_TUNER_SUB_RDS) ?
+ STE_TRUE : STE_FALSE;
+ if (modulator->txsubchans & V4L2_TUNER_SUB_STEREO)
+ stereo_status = STE_TRUE;
+ else if (modulator->txsubchans & V4L2_TUNER_SUB_MONO)
+ stereo_status = STE_FALSE;
+ cg2900_device.v_tx_stereo_status = stereo_status;
+ ste_fm_set_tx_default_settings(freq_low,
+ band,
+ grid,
+ cg2900_device.v_tx_rds_enabled,
+ cg2900_device.
+ v_tx_stereo_status);
+ } else {
+ /* Mode was FM Tx only, change the RDS settings or stereo mode
+ * if they are changed by application */
+ rds_status = (modulator->txsubchans & V4L2_TUNER_SUB_RDS) ?
+ STE_TRUE : STE_FALSE;
+ if (modulator->txsubchans & V4L2_TUNER_SUB_STEREO)
+ stereo_status = STE_TRUE;
+ else if (modulator->txsubchans & V4L2_TUNER_SUB_MONO)
+ stereo_status = STE_FALSE;
+ if (stereo_status != cg2900_device.v_tx_stereo_status) {
+ cg2900_device.v_tx_stereo_status = stereo_status;
+ status = ste_fm_set_mode(stereo_status);
+ }
+ if (rds_status != cg2900_device.v_tx_rds_enabled) {
+ cg2900_device.v_tx_rds_enabled = rds_status;
+ status = ste_fm_tx_rds(rds_status);
+ }
+ }
+
+ if (STE_STATUS_OK == status)
+ return 0;
+ else
+ return -EINVAL;
+}
+
+/**
+ * vidioc_get_frequency()- Get the Current FM Frequnecy.
* This function is used to get the currently tuned
* frequency on FM Radio. This function is called when the application
* issues the IOCTL VIDIOC_G_FREQUENCY
*
- * @file: Pointer to the file structure
- * @priv: Pointer to the previous data of file structure.
- * @arg: Pointer to the v4l2_frequency structure.
+ * @file: File structure.
+ * @priv: Previous data of file structure.
+ * @freq: v4l2_frequency structure.
*
* Returns:
* 0 when no error
* -EINVAL: otherwise
*/
-static int vidioc_g_frequency(
- struct file *file,
- void *priv,
- struct v4l2_frequency *arg
- )
+static int vidioc_get_frequency(struct file *file,
+ void *priv, struct v4l2_frequency *freq)
{
- struct v4l2_frequency *v4l2_freq = arg;
- uint8_t status;
- u32 freq;
+ u8 status;
+ u32 frequency;
int ret_val = 0;
- FM_DEBUG_REPORT("vidioc_g_frequency: Status = %d",
- g_radio_cg2900_device->v_seekstatus);
- /* Check whether seek was in progress or not */
- os_lock();
-
- if (g_radio_cg2900_device->v_seekstatus == FMR_SEEK_IN_PROGRESS) {
+ FM_DEBUG_REPORT("vidioc_get_frequency: Status = %d",
+ cg2900_device.v_seekstatus);
+ status = ste_fm_get_frequency(&frequency);
+ if (cg2900_device.v_seekstatus == FMR_SEEK_IN_PROGRESS) {
/* Check if seek is finished or not */
if (STE_EVENT_SEARCH_CHANNEL_FOUND == global_event) {
/* seek is finished */
- g_radio_cg2900_device->v_frequency =
- HZ_2_V4L2(search_freq);
- v4l2_freq->frequency =
- g_radio_cg2900_device->v_frequency;
- /* FM_DEBUG_REPORT("VIDIOC_G_FREQUENCY: \
- STE_EVENT_SEARCH_CHANNEL_FOUND, \
- freq= %d SearchFreq = %d", \
- g_radio_cg2900_device->v_frequency, \
- search_freq); */
- g_radio_cg2900_device->v_seekstatus = FMR_SEEK_NONE;
- global_event = STE_EVENT_NO_EVENT;
- ret_val = 0;
- } else if (STE_EVENT_NO_CHANNELS_FOUND == global_event) {
- /* seek is finished */
- g_radio_cg2900_device->v_seekstatus = FMR_SEEK_NONE;
+ os_lock();
+ cg2900_device.v_frequency = HZ_TO_V4L2(frequency);
+ freq->frequency = cg2900_device.v_frequency;
+ /* FM_DEBUG_REPORT("VIDIOC_G_FREQUENCY: "\
+ "STE_EVENT_SEARCH_CHANNEL_FOUND, "\
+ "freq= %d SearchFreq = %d",
+ cg2900_device.v_frequency,
+ frequency); */
+ cg2900_device.v_seekstatus = FMR_SEEK_NONE;
global_event = STE_EVENT_NO_EVENT;
- v4l2_freq->frequency =
- g_radio_cg2900_device->v_frequency;
+ os_unlock();
ret_val = 0;
}
} else {
- global_event = STE_EVENT_NO_EVENT;
- status = ste_fm_get_frequency((uint32_t *)&freq);
+ os_lock();
if (STE_STATUS_OK == status) {
- g_radio_cg2900_device->v_frequency = HZ_2_V4L2(freq);
- v4l2_freq->frequency =
- g_radio_cg2900_device->v_frequency;
+ cg2900_device.v_frequency = HZ_TO_V4L2(frequency);
+ freq->frequency = cg2900_device.v_frequency;
ret_val = 0;
} else {
- v4l2_freq->frequency =
- g_radio_cg2900_device->v_frequency;
+ freq->frequency = cg2900_device.v_frequency;
ret_val = -EINVAL;
}
+ os_unlock();
}
- os_unlock();
- FM_DEBUG_REPORT("vidioc_g_frequency: Status = %d, returning",
- g_radio_cg2900_device->v_seekstatus);
+ FM_DEBUG_REPORT("vidioc_get_frequency: Status = %d, returning",
+ cg2900_device.v_seekstatus);
return ret_val;
}
/**
- * vidioc_s_frequency()- Set the FM Frequnecy.
+ * vidioc_set_frequency()- Set the FM Frequnecy.
* This function is used to set the frequency
* on FM Radio. This function is called when the application
* issues the IOCTL VIDIOC_S_FREQUENCY
*
- * @file: Pointer to the file structure
- * @priv: Pointer to the previous data of file structure.
- * @arg: Pointer to the v4l2_frequency structure.
+ * @file: File structure.
+ * @priv: Previous data of file structure.
+ * @freq: v4l2_frequency structure.
*
* Returns:
* 0 when no error
* -EINVAL: otherwise
*/
-static int vidioc_s_frequency(
- struct file *file,
- void *priv,
- struct v4l2_frequency *arg
- )
+static int vidioc_set_frequency(struct file *file,
+ void *priv, struct v4l2_frequency *freq)
{
- const struct v4l2_frequency *v = arg;
- __u32 freq = v->frequency;
- uint8_t status;
+ u32 frequency = freq->frequency;
+ u8 status;
- FM_DEBUG_REPORT("vidioc_s_frequency: Frequency = "\
- "%d ", V4L2_2_HZ(freq));
+ FM_DEBUG_REPORT("vidioc_set_frequency: Frequency = "
+ "%d ", V4L2_TO_HZ(frequency));
os_lock();
global_event = STE_EVENT_NO_EVENT;
- search_freq = 0;
- no_of_scanfreq = 0;
+ no_of_scan_freq = 0;
os_unlock();
- g_radio_cg2900_device->v_seekstatus = FMR_SEEK_NONE;
- g_radio_cg2900_device->v_frequency = freq;
- status = ste_fm_set_frequency(V4L2_2_HZ(freq));
+ cg2900_device.v_seekstatus = FMR_SEEK_NONE;
+ cg2900_device.v_frequency = frequency;
+ status = ste_fm_set_frequency(V4L2_TO_HZ(frequency));
if (STE_STATUS_OK == status)
return 0;
else
@@ -495,80 +695,77 @@ static int vidioc_s_frequency(
}
/**
- * vidioc_queryctrl()- Query the FM Driver control features.
+ * vidioc_query_ctrl()- Query the FM Driver control features.
* This function is used to query the control features on FM Radio.
* This function is called when the application
* issues the IOCTL VIDIOC_QUERYCTRL
*
- * @file: Pointer to the file structure
- * @priv: Pointer to the previous data of file structure.
- * @arg: Pointer to the v4l2_queryctrl structure.
+ * @file: File structure.
+ * @priv: Previous data of file structure.
+ * @query_ctrl: v4l2_queryctrl structure.
*
* Returns:
* 0 when no error
* -EINVAL: otherwise
*/
-static int vidioc_queryctrl(
- struct file *file,
- void *priv,
- struct v4l2_queryctrl *arg
- )
+static int vidioc_query_ctrl(struct file *file,
+ void *priv, struct v4l2_queryctrl *query_ctrl)
{
- struct v4l2_queryctrl *v = arg;
- FM_DEBUG_REPORT("vidioc_queryctrl");
+ FM_DEBUG_REPORT("vidioc_query_ctrl");
/* Check which control is requested */
- switch (v->id) {
- /* Audio Mute. This is a hardware function in the CG2900 radio */
+ switch (query_ctrl->id) {
+ /* Audio Mute. This is a hardware function in the CG2900
+ radio */
case V4L2_CID_AUDIO_MUTE:
- FM_DEBUG_REPORT("vidioc_queryctrl: V4L2_CID_AUDIO_MUTE");
- v->type = V4L2_CTRL_TYPE_BOOLEAN;
- v->minimum = 0;
- v->maximum = 1;
- v->step = 1;
- v->default_value = 0;
- v->flags = 0;
- strncpy(v->name, "CG2900 Mute", 32); /* Max 32 bytes */
+ FM_DEBUG_REPORT("vidioc_query_ctrl: V4L2_CID_AUDIO_MUTE");
+ query_ctrl->type = V4L2_CTRL_TYPE_BOOLEAN;
+ query_ctrl->minimum = 0;
+ query_ctrl->maximum = 1;
+ query_ctrl->step = 1;
+ query_ctrl->default_value = 0;
+ query_ctrl->flags = 0;
+ strncpy(query_ctrl->name, "CG2900 Mute", 32);
break;
/* Audio Volume. Not implemented in
* hardware. just a dummy function. */
case V4L2_CID_AUDIO_VOLUME:
- FM_DEBUG_REPORT("vidioc_queryctrl: V4L2_CID_AUDIO_VOLUME");
- strncpy(v->name, "CG2900 Volume", 32); /* Max 32 bytes */
- v->minimum = 0x00;
- v->maximum = 0x15;
- v->step = 1;
- v->default_value = 0x15;
- v->flags = 0;
- v->type = V4L2_CTRL_TYPE_INTEGER;
+ FM_DEBUG_REPORT("vidioc_query_ctrl: V4L2_CID_AUDIO_VOLUME");
+ strncpy(query_ctrl->name, "CG2900 Volume", 32);
+ query_ctrl->minimum = MIN_ANALOG_VOLUME;
+ query_ctrl->maximum = MAX_ANALOG_VOLUME;
+ query_ctrl->step = 1;
+ query_ctrl->default_value = MAX_ANALOG_VOLUME;
+ query_ctrl->flags = 0;
+ query_ctrl->type = V4L2_CTRL_TYPE_INTEGER;
break;
case V4L2_CID_AUDIO_BALANCE:
- FM_DEBUG_REPORT("vidioc_queryctrl: V4L2_CID_AUDIO_BALANCE ");
- strncpy(v->name, "CG2900 Audio Balance", 32);
- v->type = V4L2_CTRL_TYPE_INTEGER;
- v->minimum = 0x0000;
- v->maximum = 0xFFFF;
- v->step = 0x0001;
- v->default_value = 0x0000;
- v->flags = 0;
+ FM_DEBUG_REPORT("vidioc_query_ctrl: V4L2_CID_AUDIO_BALANCE ");
+ strncpy(query_ctrl->name, "CG2900 Audio Balance", 32);
+ query_ctrl->type = V4L2_CTRL_TYPE_INTEGER;
+ query_ctrl->minimum = 0x0000;
+ query_ctrl->maximum = 0xFFFF;
+ query_ctrl->step = 0x0001;
+ query_ctrl->default_value = 0x0000;
+ query_ctrl->flags = 0;
break;
/* Explicitely list some CIDs to produce a
* verbose output in debug mode. */
case V4L2_CID_AUDIO_BASS:
- FM_DEBUG_REPORT("vidioc_queryctrl: "\
+ FM_DEBUG_REPORT("vidioc_query_ctrl: "
"V4L2_CID_AUDIO_BASS (unsupported)");
return -EINVAL;
case V4L2_CID_AUDIO_TREBLE:
- FM_DEBUG_REPORT("vidioc_queryctrl: "\
+ FM_DEBUG_REPORT("vidioc_query_ctrl: "
"V4L2_CID_AUDIO_TREBLE (unsupported)");
return -EINVAL;
default:
- FM_DEBUG_REPORT("vidioc_queryctrl: "\
- "--> unsupported id = %d", (int)v->id);
+ FM_DEBUG_REPORT("vidioc_query_ctrl: "
+ "--> unsupported id = %d", (int)query_ctrl->id);
return -EINVAL;
}
@@ -576,165 +773,186 @@ static int vidioc_queryctrl(
}
/**
- * vidioc_g_ctrl()- Get the value of a particular Control.
+ * vidioc_get_ctrl()- Get the value of a particular Control.
* This function is used to get the value of a
* particular control from the FM Driver. This function is called
* when the application issues the IOCTL VIDIOC_G_CTRL
*
- * @file: Pointer to the file structure
- * @priv: Pointer to the previous data of file structure.
- * @arg: Pointer to the v4l2_control structure.
+ * @file: File structure.
+ * @priv: Previous data of file structure.
+ * @ctrl: v4l2_control structure.
*
* Returns:
* 0 when no error
* -EINVAL: otherwise
*/
-static int vidioc_g_ctrl(
- struct file *file,
- void *priv,
- struct v4l2_control *arg
- )
+static int vidioc_get_ctrl(struct file *file,
+ void *priv, struct v4l2_control *ctrl)
{
- struct v4l2_control *v = arg;
- uint8_t status;
- uint8_t value;
- uint16_t rssi;
+ u8 status = STE_STATUS_OK;
+ u8 value;
+ u16 rssi;
+ u8 antenna;
+ u16 conclusion;
+ int ret_val = -EINVAL;
+
+ FM_DEBUG_REPORT("vidioc_get_ctrl");
- FM_DEBUG_REPORT("vidioc_g_ctrl") ;
- if (v->id == V4L2_CID_AUDIO_VOLUME) {
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_VOLUME:
status = ste_fm_get_volume(&value);
- v->value = value;
- g_radio_cg2900_device->v_volume = value;
- } else if (v->id == V4L2_CID_AUDIO_MUTE) {
- v->value = g_radio_cg2900_device->v_muted;
- } else if (v->id == V4L2_CID_AUDIO_BALANCE) {
- v->value = g_radio_cg2900_device->v_audiopath;
- } else if (v->id == V4L2_CID_CG2900_RADIO_RSSI_THRESHOLD) {
- v->value = g_radio_cg2900_device->v_rssi_threshold;
- } else if (v->id == V4L2_CID_CG2900_RADIO_RSSI_LEVEL) {
- status = ste_fm_get_signal_strength(&rssi);
- FM_DEBUG_REPORT("vidioc_g_ctrl: rssi = %d", rssi);
- v->value = rssi;
+ if (STE_STATUS_OK == status) {
+ ctrl->value = value;
+ cg2900_device.v_volume = value;
+ ret_val = 0;
+ }
+ break;
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value = cg2900_device.v_muted;
+ ret_val = 0;
+ break;
+ case V4L2_CID_AUDIO_BALANCE:
+ ctrl->value = cg2900_device.v_audiopath;
+ ret_val = 0;
+ break;
+ case V4L2_CID_CG2900_RADIO_RSSI_THRESHOLD:
+ ctrl->value = cg2900_device.v_rssi_threshold;
+ ret_val = 0;
+ break;
+ case V4L2_CID_CG2900_RADIO_SELECT_ANTENNA:
+ status = ste_fm_get_antenna(&antenna);
+ FM_DEBUG_REPORT("vidioc_get_ctrl: Antenna = %d", antenna);
+ if (STE_STATUS_OK == status) {
+ ctrl->value = antenna;
+ ret_val = 0;
+ }
+ break;
+ case V4L2_CID_CG2900_RADIO_RDS_AF_UPDATE_GET_RESULT:
+ status = ste_fm_af_update_get_result(&rssi);
+ FM_DEBUG_REPORT("vidioc_get_ctrl: AF RSSI Level = %d", rssi);
+ if (STE_STATUS_OK == status) {
+ ctrl->value = rssi;
+ ret_val = 0;
+ }
+ break;
+ case V4L2_CID_CG2900_RADIO_RDS_AF_SWITCH_GET_RESULT:
+ status = ste_fm_af_switch_get_result(&conclusion);
+ FM_DEBUG_REPORT("vidioc_get_ctrl: AF Switch conclusion = %d",
+ conclusion);
+ if (STE_STATUS_OK == status) {
+ ctrl->value = conclusion;
+ ret_val = 0;
+ }
+ break;
+ default:
+ FM_DEBUG_REPORT("vidioc_get_ctrl: "
+ "unsupported (id = %d)", (int)ctrl->id);
+ ret_val = -EINVAL;
}
- return 0;
+ return ret_val;
}
/**
- * vidioc_s_ctrl()- Set the value of a particular Control.
+ * vidioc_set_ctrl()- Set the value of a particular Control.
* This function is used to set the value of a
* particular control from the FM Driver. This function is called when the
* application issues the IOCTL VIDIOC_S_CTRL
*
- * @file: Pointer to the file structure
- * @priv: Pointer to the previous data of file structure.
- * @arg: Pointer to the v4l2_control structure.
+ * @file: File structure.
+ * @priv: Previous data of file structure.
+ * @ctrl: v4l2_control structure.
*
* Returns:
* 0 when no error
+ * -ERANGE when the parameter is out of range.
* -EINVAL: otherwise
*/
-static int vidioc_s_ctrl(
- struct file *file,
- void *priv,
- struct v4l2_control *arg
- )
+static int vidioc_set_ctrl(struct file *file,
+ void *priv, struct v4l2_control *ctrl)
{
- struct v4l2_control *v = arg;
- uint8_t status = STE_STATUS_OK;
+ u8 status = STE_STATUS_OK;
int ret_val;
- FM_DEBUG_REPORT("vidioc_s_ctrl");
+ FM_DEBUG_REPORT("vidioc_set_ctrl");
/* Check which control is requested */
- switch (v->id) {
- /* Audio Mute. This is a hardware function in the CG2900 radio */
+ switch (ctrl->id) {
+ /*Audio Mute. This is a hardware function in the CG2900 radio*/
case V4L2_CID_AUDIO_MUTE:
- FM_DEBUG_REPORT("vidioc_s_ctrl: "\
- "V4L2_CID_AUDIO_MUTE, "\
- "value = %d", v->value);
- if (v->value > 1 && v->value < 0)
+ FM_DEBUG_REPORT("vidioc_set_ctrl: "
+ "V4L2_CID_AUDIO_MUTE, "
+ "value = %d", ctrl->value);
+ if (ctrl->value > 1 && ctrl->value < 0)
return -ERANGE;
- if (v->value) {
- FM_DEBUG_REPORT("vidioc_s_ctrl: Ctrl_Id = "\
- "V4L2_CID_AUDIO_MUTE, "\
+ if (ctrl->value) {
+ FM_DEBUG_REPORT("vidioc_set_ctrl: Ctrl_Id = "
+ "V4L2_CID_AUDIO_MUTE, "
"Muting the Radio");
status = ste_fm_mute();
} else {
- FM_DEBUG_REPORT("vidioc_s_ctrl: "\
- "Ctrl_Id = V4L2_CID_AUDIO_MUTE, "\
+ FM_DEBUG_REPORT("vidioc_set_ctrl: "
+ "Ctrl_Id = V4L2_CID_AUDIO_MUTE, "
"UnMuting the Radio");
status = ste_fm_unmute();
}
if (STE_STATUS_OK == status) {
- g_radio_cg2900_device->v_muted = v->value;
+ cg2900_device.v_muted = ctrl->value;
ret_val = 0;
- } else
+ } else {
ret_val = -EINVAL;
+ }
break;
case V4L2_CID_AUDIO_VOLUME:
- FM_DEBUG_REPORT("vidioc_s_ctrl: "\
- "V4L2_CID_AUDIO_VOLUME, "\
- "value = %d", v->value);
- if (v->value > 20 && v->value < 0)
+ FM_DEBUG_REPORT("vidioc_set_ctrl: "
+ "V4L2_CID_AUDIO_VOLUME, "
+ "value = %d", ctrl->value);
+ if (ctrl->value > 20 && ctrl->value < 0)
return -ERANGE;
- status = ste_fm_set_volume(v->value);
+ status = ste_fm_set_volume(ctrl->value);
if (STE_STATUS_OK == status) {
- g_radio_cg2900_device->v_volume = v->value;
+ cg2900_device.v_volume = ctrl->value;
ret_val = 0;
- } else
+ } else {
ret_val = -EINVAL;
+ }
break;
case V4L2_CID_AUDIO_BALANCE:
- FM_DEBUG_REPORT("vidioc_s_ctrl: "\
- "V4L2_CID_AUDIO_BALANCE, "\
- "value = %d", v->value);
- status = ste_fm_set_audio_balance(v->value);
+ FM_DEBUG_REPORT("vidioc_set_ctrl: "
+ "V4L2_CID_AUDIO_BALANCE, "
+ "value = %d", ctrl->value);
+ status = ste_fm_set_audio_balance(ctrl->value);
if (STE_STATUS_OK == status) {
- g_radio_cg2900_device->v_audiopath = v->value;
+ cg2900_device.v_audiopath = ctrl->value;
ret_val = 0;
- } else
+ } else {
ret_val = -EINVAL;
+ }
break;
case V4L2_CID_CG2900_RADIO_CHIP_STATE:
- FM_DEBUG_REPORT("vidioc_s_ctrl: "\
- "V4L2_CID_radio_cg2900_RADIO_CHIP_STATE, "\
- "value = %d", v->value);
- if (V4L2_CG2900_RADIO_STANDBY == v->value) {
+ FM_DEBUG_REPORT("vidioc_set_ctrl: "
+ "V4L2_CID_CG2900_RADIO_CHIP_STATE, "
+ "value = %d", ctrl->value);
+ if (V4L2_CG2900_RADIO_STANDBY == ctrl->value)
status = ste_fm_standby();
- g_radio_cg2900_device->v_state = FMR_STANDBY;
- } else if (V4L2_CG2900_RADIO_POWERUP == v->value) {
+ else if (V4L2_CG2900_RADIO_POWERUP == ctrl->value)
status = ste_fm_power_up_from_standby();
- g_radio_cg2900_device->v_state = FMR_SWITCH_ON;
- }
- if (STE_STATUS_OK == status)
+ if (STE_STATUS_OK == status) {
+ if (V4L2_CG2900_RADIO_STANDBY == ctrl->value)
+ cg2900_device.v_state = FMR_STANDBY;
+ else if (V4L2_CG2900_RADIO_POWERUP == ctrl->value)
+ cg2900_device.v_state = FMR_SWITCH_ON;
ret_val = 0;
- else
+ } else {
ret_val = -EINVAL;
- break;
-
- case V4L2_CID_CG2900_RADIO_RDS_STATE:
- FM_DEBUG_REPORT("vidioc_s_ctrl: "\
- "V4L2_CID_radio_cg2900_RADIO_RDS_STATE, "\
- "value = %d", v->value);
- if (V4L2_CG2900_RADIO_RDS_ON == v->value) {
- status = ste_fm_rds_on();
- g_radio_cg2900_device->v_rds_enabled = STE_TRUE;
- } else if (V4L2_CG2900_RADIO_RDS_OFF == v->value) {
- status = ste_fm_rds_off();
- g_radio_cg2900_device->v_rds_enabled = STE_FALSE;
}
- if (STE_STATUS_OK == status)
- ret_val = 0;
- else
- ret_val = -EINVAL;
break;
case V4L2_CID_CG2900_RADIO_SELECT_ANTENNA:
- FM_DEBUG_REPORT("vidioc_s_ctrl: "\
- "V4L2_CID_radio_cg2900_RADIO_SELECT_ANTENNA, "\
- "value = %d", v->value);
- status = ste_fm_select_antenna(v->value);
+ FM_DEBUG_REPORT("vidioc_set_ctrl: "
+ "V4L2_CID_CG2900_RADIO_SELECT_ANTENNA, "
+ "value = %d", ctrl->value);
+ status = ste_fm_select_antenna(ctrl->value);
if (STE_STATUS_OK == status)
ret_val = 0;
else
@@ -742,58 +960,79 @@ static int vidioc_s_ctrl(
break;
case V4L2_CID_CG2900_RADIO_BANDSCAN:
- FM_DEBUG_REPORT("vidioc_s_ctrl: "\
- "V4L2_CID_radio_cg2900_RADIO_BANDSCAN, "\
- "value = %d", v->value);
- if (V4L2_CG2900_RADIO_BANDSCAN_START == v->value) {
- no_of_scanfreq = 0;
+ FM_DEBUG_REPORT("vidioc_set_ctrl: "
+ "V4L2_CID_CG2900_RADIO_BANDSCAN, "
+ "value = %d", ctrl->value);
+ if (V4L2_CG2900_RADIO_BANDSCAN_START == ctrl->value) {
+ no_of_scan_freq = 0;
status = ste_fm_start_band_scan();
- g_radio_cg2900_device->v_seekstatus =
- FMR_SEEK_IN_PROGRESS;
- } else if (V4L2_CG2900_RADIO_BANDSCAN_STOP == v->value) {
+ } else if (V4L2_CG2900_RADIO_BANDSCAN_STOP == ctrl->value) {
status = ste_fm_stop_scan();
- /* Clear the flag, just in case there
- * is timeout in scan, application can clear
- * this flag also */
- g_radio_cg2900_device->v_seekstatus = FMR_SEEK_NONE;
}
- if (STE_STATUS_OK == status)
+ if (STE_STATUS_OK == status) {
+ cg2900_device.v_seekstatus = FMR_SEEK_IN_PROGRESS;
ret_val = 0;
- else
+ } else {
ret_val = -EINVAL;
+ }
+ break;
+
+ case V4L2_CID_CG2900_RADIO_BLOCKSCAN_START:
+ FM_DEBUG_REPORT("vidioc_set_ctrl: "
+ "V4L2_CID_CG2900_RADIO_BLOCKSCAN_START");
+ no_of_block_scan_freq = 0;
+ status = ste_fm_start_block_scan();
+ if (STE_STATUS_OK == status) {
+ cg2900_device.v_seekstatus = FMR_SEEK_IN_PROGRESS;
+ ret_val = 0;
+ } else {
+ ret_val = -EINVAL;
+ }
break;
case V4L2_CID_CG2900_RADIO_RSSI_THRESHOLD:
- FM_DEBUG_REPORT("vidioc_s_ctrl: "\
- "V4L2_CID_radio_cg2900_RADIO_RSSI_THRESHOLD "\
- "= %d", v->value);
- status = ste_fm_set_rssi_threshold(v->value);
+ FM_DEBUG_REPORT("vidioc_set_ctrl: "
+ "V4L2_CID_CG2900_RADIO_RSSI_THRESHOLD "
+ "= %d", ctrl->value);
+ status = ste_fm_set_rssi_threshold(ctrl->value);
if (STE_STATUS_OK == status) {
- g_radio_cg2900_device->v_rssi_threshold = v->value;
+ cg2900_device.v_rssi_threshold = ctrl->value;
ret_val = 0;
- } else
+ } else {
+ ret_val = -EINVAL;
+ }
+ break;
+
+ case V4L2_CID_CG2900_RADIO_RDS_AF_UPDATE_START:
+ FM_DEBUG_REPORT("vidioc_set_ctrl: "
+ "V4L2_CID_CG2900_RADIO_RDS_AF_UPDATE_START "
+ "freq = %d Hz", ctrl->value);
+ status = ste_fm_af_update_start(ctrl->value);
+ if (STE_STATUS_OK == status)
+ ret_val = 0;
+ else
ret_val = -EINVAL;
break;
default:
- FM_DEBUG_REPORT("vidioc_s_ctrl: "\
- "unsupported (id = %d)", (int)v->id);
- return -EINVAL;
+ FM_DEBUG_REPORT("vidioc_set_ctrl: "
+ "unsupported (id = %d)", (int)ctrl->id);
+ ret_val = -EINVAL;
}
return ret_val;
}
/**
- * vidioc_g_ext_ctrls()- Get the values of a particular control.
+ * vidioc_get_ext_ctrls()- Get the values of a particular control.
* This function is used to get the value of a
* particular control from the FM Driver. This is used when the data to
* be received is more than 1 paramter. This function is called when the
* application issues the IOCTL VIDIOC_G_EXT_CTRLS
*
- * @file: Pointer to the file structure
- * @priv: Pointer to the previous data of file structure.
- * @arg: Pointer to the v4l2_ext_controls structure.
+ * @file: File structure.
+ * @priv: Previous data of file structure.
+ * @ext_ctrl: v4l2_ext_controls structure.
*
* Returns:
* 0 when no error
@@ -801,346 +1040,715 @@ static int vidioc_s_ctrl(
* by application.
* -EINVAL: otherwise
*/
-static int vidioc_g_ext_ctrls(
- struct file *file,
- void *priv,
- struct v4l2_ext_controls *arg
- )
+static int vidioc_get_ext_ctrls(struct file *file,
+ void *priv, struct v4l2_ext_controls *ext_ctrl)
{
- struct v4l2_ext_controls *v = arg;
- u32 *p;
+ u32 *dest_buffer;
int index = 0;
int count = 0;
- int ret_val;
- uint8_t status;
-
- FM_DEBUG_REPORT("vidioc_g_ext_ctrls: Id = %04x", v->controls->id) ;
+ int ret_val = -EINVAL;
+ u8 status;
+
+ FM_DEBUG_REPORT("vidioc_get_ext_ctrls: Id = %04x,"
+ "ext_ctrl->ctrl_class = %04x",
+ ext_ctrl->controls->id, ext_ctrl->ctrl_class);
+ if (ext_ctrl->ctrl_class != V4L2_CTRL_CLASS_FM_TX &&
+ ext_ctrl->ctrl_class != V4L2_CTRL_CLASS_USER) {
+ FM_ERR_REPORT("vidioc_get_ext_ctrls: Unsupported "
+ "ctrl_class = %04x", ext_ctrl->ctrl_class);
+ return ret_val;
+ }
- switch (v->controls->id) {
+ switch (ext_ctrl->controls->id) {
case V4L2_CID_CG2900_RADIO_BANDSCAN_GET_RESULTS:
{
- if (g_radio_cg2900_device->v_seekstatus ==
+ if (cg2900_device.v_seekstatus ==
FMR_SEEK_IN_PROGRESS) {
if (global_event ==
- STE_EVENT_SCAN_CHANNELS_FOUND) {
+ STE_EVENT_SCAN_CHANNELS_FOUND) {
/* Check to get Scan Result */
- os_lock();
status =
- ste_fm_get_scan_result(&no_of_scanfreq,
- scanfreq,
- scanfreq_rssi_level);
- os_unlock();
+ ste_fm_get_scan_result
+ (&no_of_scan_freq, scanfreq,
+ scanfreq_rssi_level);
+ if (STE_STATUS_OK != status) {
+ FM_ERR_REPORT
+ ("vidioc_get_ext_ctrls: "
+ "ste_fm_get_scan_result: "
+ "returned %d", status);
+ return ret_val;
+ }
}
}
- FM_DEBUG_REPORT("vidioc_g_ext_ctrls: "\
- "SeekStatus = %d, GlobalEvent = %d, "\
+ FM_DEBUG_REPORT("vidioc_get_ext_ctrls: "
+ "SeekStatus = %d, GlobalEvent = %d, "
"numchannels = %d",
- g_radio_cg2900_device->v_seekstatus,
- global_event,
- no_of_scanfreq);
- if (v->ctrl_class == V4L2_CTRL_CLASS_USER) {
- if (v->controls->size == 0 && \
- v->controls->string == NULL) {
- if (
- g_radio_cg2900_device->v_seekstatus == \
- FMR_SEEK_IN_PROGRESS && \
- STE_EVENT_SCAN_CHANNELS_FOUND \
- == global_event) {
- v->controls->size = \
- no_of_scanfreq;
- g_radio_cg2900_device->v_seekstatus
- = FMR_SEEK_NONE;
- global_event = \
- STE_EVENT_NO_EVENT;
+ cg2900_device.v_seekstatus,
+ global_event, no_of_scan_freq);
+ if (ext_ctrl->ctrl_class == V4L2_CTRL_CLASS_USER) {
+ if (ext_ctrl->controls->size == 0 &&
+ ext_ctrl->controls->string == NULL) {
+ if (cg2900_device.v_seekstatus ==
+ FMR_SEEK_IN_PROGRESS &&
+ STE_EVENT_SCAN_CHANNELS_FOUND
+ == global_event) {
+ os_lock();
+ ext_ctrl->controls->size =
+ no_of_scan_freq;
+ cg2900_device.v_seekstatus
+ = FMR_SEEK_NONE;
+ global_event =
+ STE_EVENT_NO_EVENT;
+ os_unlock();
return -ENOSPC;
}
- if (
- g_radio_cg2900_device->v_seekstatus == \
- FMR_SEEK_IN_PROGRESS && \
- STE_EVENT_NO_CHANNELS_FOUND \
- == global_event) {
- v->count = 0;
- g_radio_cg2900_device->v_seekstatus
- = FMR_SEEK_NONE;
- global_event = \
- STE_EVENT_NO_EVENT;
- return 0;
- }
- } else if (v->controls->string != NULL) {
- os_lock();
- p = (u32 *) v->controls->string;
- while (index < no_of_scanfreq) {
- *(p + count + 0) = \
- HZ_2_V4L2(scanfreq[index]);
- *(p + count + 1) = \
- scanfreq_rssi_level[index];
- /* FM_DEBUG_REPORT \
- ("VIDIOC_GET_SCAN: \
- freq = %d, RSSI = %d ", \
- *(p + count + 0), \
- *(p + count + 1)); */
+ } else if (ext_ctrl->controls->string != NULL) {
+ dest_buffer =
+ (u32 *) ext_ctrl->controls->string;
+ while (index < no_of_scan_freq) {
+ *(dest_buffer + count + 0) =
+ HZ_TO_V4L2(scanfreq[index]);
+ *(dest_buffer + count + 1) =
+ scanfreq_rssi_level[index];
count += 2;
index++;
}
ret_val = 0;
- os_unlock();
- return 0;
+ return ret_val;
+ }
+ }
+ break;
+ }
+ case V4L2_CID_CG2900_RADIO_BLOCKSCAN_GET_RESULTS:
+ {
+ if (cg2900_device.v_seekstatus ==
+ FMR_SEEK_IN_PROGRESS) {
+ if (global_event ==
+ STE_EVENT_BLOCK_SCAN_CHANNELS_FOUND) {
+ /* Check to get BlockScan Result */
+ status =
+ ste_fm_get_block_scan_result
+ (&no_of_block_scan_freq,
+ block_scan_rssi_level);
+ if (STE_STATUS_OK != status) {
+ FM_ERR_REPORT
+ ("vidioc_get_ext_ctrls: "
+ "ste_fm_get_block_scan_"
+ "result: " "returned %d",
+ status);
+ return ret_val;
+ }
}
}
+ FM_DEBUG_REPORT("vidioc_get_ext_ctrls: "
+ "SeekStatus = %d, GlobalEvent = %d, "
+ "numchannels = %d",
+ cg2900_device.v_seekstatus,
+ global_event, no_of_block_scan_freq);
+ if (ext_ctrl->ctrl_class == V4L2_CTRL_CLASS_USER) {
+ if (ext_ctrl->controls->size == 0 &&
+ ext_ctrl->controls->string == NULL) {
+ if (cg2900_device.v_seekstatus ==
+ FMR_SEEK_IN_PROGRESS &&
+ STE_EVENT_BLOCK_SCAN_CHANNELS_FOUND
+ == global_event) {
+ os_lock();
+ ext_ctrl->controls->size =
+ no_of_block_scan_freq;
+ cg2900_device.v_seekstatus
+ = FMR_SEEK_NONE;
+ global_event =
+ STE_EVENT_NO_EVENT;
+ os_unlock();
+ return -ENOSPC;
+ }
+ } else if (ext_ctrl->controls->size >=
+ no_of_block_scan_freq &&
+ ext_ctrl->controls->string != NULL) {
+ dest_buffer =
+ (u32 *) ext_ctrl->controls->string;
+ while (index < no_of_block_scan_freq) {
+ *(dest_buffer + index) =
+ block_scan_rssi_level
+ [index];
+ index++;
+ }
+ ret_val = 0;
+ return ret_val;
+ }
+ }
+ break;
+ }
+ case V4L2_CID_RDS_TX_DEVIATION:
+ {
+ FM_DEBUG_REPORT("vidioc_get_ext_ctrls: "
+ "V4L2_CID_RDS_TX_DEVIATION");
+ if (V4L2_CTRL_CLASS_FM_TX != ext_ctrl->ctrl_class) {
+ FM_ERR_REPORT("Invalid Ctrl Class = %d",
+ ext_ctrl->ctrl_class);
+ return -EINVAL;
+ }
+ status = ste_fm_tx_get_rds_deviation((u16 *) &
+ ext_ctrl->
+ controls->value);
+ if (status == STE_STATUS_OK)
+ ret_val = 0;
+ break;
+ }
+ case V4L2_CID_PILOT_TONE_ENABLED:
+ {
+ FM_DEBUG_REPORT("vidioc_get_ext_ctrls: "
+ "V4L2_CID_PILOT_TONE_ENABLED");
+ if (V4L2_CTRL_CLASS_FM_TX != ext_ctrl->ctrl_class) {
+ FM_ERR_REPORT("Invalid Ctrl Class = %d",
+ ext_ctrl->ctrl_class);
+ return -EINVAL;
+ }
+ status = ste_fm_tx_get_pilot_tone_status((bool *) &
+ ext_ctrl->
+ controls->
+ value);
+ if (status == STE_STATUS_OK)
+ ret_val = 0;
+ break;
+ }
+ case V4L2_CID_PILOT_TONE_DEVIATION:
+ {
+ FM_DEBUG_REPORT("vidioc_get_ext_ctrls: "
+ "V4L2_CID_PILOT_TONE_DEVIATION");
+ if (V4L2_CTRL_CLASS_FM_TX != ext_ctrl->ctrl_class) {
+ FM_ERR_REPORT("Invalid Ctrl Class = %d",
+ ext_ctrl->ctrl_class);
+ return -EINVAL;
+ }
+ status = ste_fm_tx_get_pilot_deviation((u16 *) &
+ ext_ctrl->
+ controls->value);
+ if (status == STE_STATUS_OK)
+ ret_val = 0;
+ break;
+ }
+ case V4L2_CID_TUNE_PREEMPHASIS:
+ {
+ FM_DEBUG_REPORT("vidioc_get_ext_ctrls: "
+ "V4L2_CID_TUNE_PREEMPHASIS");
+ if (V4L2_CTRL_CLASS_FM_TX != ext_ctrl->ctrl_class) {
+ FM_ERR_REPORT("Invalid Ctrl Class = %d",
+ ext_ctrl->ctrl_class);
+ return -EINVAL;
+ }
+ status = ste_fm_tx_get_preemphasis((u8 *) &ext_ctrl->
+ controls->value);
+ if (status == STE_STATUS_OK)
+ ret_val = 0;
+ break;
+ }
+ case V4L2_CID_TUNE_POWER_LEVEL:
+ {
+ FM_DEBUG_REPORT("vidioc_get_ext_ctrls: "
+ "V4L2_CID_TUNE_POWER_LEVEL");
+ if (V4L2_CTRL_CLASS_FM_TX != ext_ctrl->ctrl_class) {
+ FM_ERR_REPORT("Invalid Ctrl Class = %d",
+ ext_ctrl->ctrl_class);
+ return -EINVAL;
+ }
+ status = ste_fm_tx_get_power_level((u16 *) &ext_ctrl->
+ controls->value);
+ if (status == STE_STATUS_OK)
+ ret_val = 0;
+ break;
+ }
+ default:
+ {
+ FM_DEBUG_REPORT("vidioc_get_ext_ctrls: "
+ "unsupported (id = %d)",
+ (int)ext_ctrl->controls->id);
+ ret_val = -EINVAL;
+ }
+ }
+
+ FM_DEBUG_REPORT("vidioc_get_ext_ctrls: returning = %d", ret_val);
+ return ret_val;
+}
+
+/**
+ * vidioc_set_ext_ctrls()- Set the values of a particular control.
+ * This function is used to set the value of a
+ * particular control on the FM Driver. This is used when the data to
+ * be set is more than 1 paramter. This function is called when the
+ * application issues the IOCTL VIDIOC_S_EXT_CTRLS
+ *
+ * @file: File structure.
+ * @priv: Previous data of file structure.
+ * @ext_ctrl: v4l2_ext_controls structure.
+ *
+ * Returns:
+ * 0 when no error
+ * -ENOSPC: when there is no space to copy the data into the buffer provided
+ * by application.
+ * -EINVAL: otherwise
+ */
+static int vidioc_set_ext_ctrls(struct file *file,
+ void *priv, struct v4l2_ext_controls *ext_ctrl)
+{
+ int ret_val = -EINVAL;
+ u8 status;
+
+ FM_DEBUG_REPORT("vidioc_set_ext_ctrls: Id = %04x, ctrl_class = %04x",
+ ext_ctrl->controls->id, ext_ctrl->ctrl_class);
+
+ if (ext_ctrl->ctrl_class != V4L2_CTRL_CLASS_FM_TX &&
+ ext_ctrl->ctrl_class != V4L2_CTRL_CLASS_USER) {
+ FM_ERR_REPORT("vidioc_set_ext_ctrls: Unsupported "
+ "ctrl_class = %04x", ext_ctrl->ctrl_class);
+ return ret_val;
+ }
+
+ switch (ext_ctrl->controls->id) {
+ case V4L2_CID_CG2900_RADIO_RDS_AF_SWITCH_START:
+ {
+ u32 af_switch_freq;
+ u16 af_switch_pi;
+ u32 *pointer;
+ if (ext_ctrl->ctrl_class == V4L2_CTRL_CLASS_USER) {
+ if (ext_ctrl->controls->size == 2 &&
+ ext_ctrl->controls->string != NULL) {
+ pointer =
+ (u32 *) ext_ctrl->controls->string;
+ os_mem_copy(&af_switch_freq,
+ pointer, sizeof(u32));
+ os_mem_copy(&af_switch_pi,
+ pointer + sizeof(u32),
+ sizeof(u16));
+ FM_DEBUG_REPORT("vidioc_set_ext_ctrls: "
+ "V4L2_CID_CG2900_RADIO_"
+ "RDS_AF_SWITCH_START: "
+ "AF Switch Freq =%d Hz "
+ "AF Switch PI = %04x",
+ af_switch_freq,
+ af_switch_pi);
+ if (af_switch_freq <
+ (FMR_CHINA_LOW_FREQ_IN_KHZ
+ * FMR_HRTZ_MULTIPLIER) ||
+ af_switch_freq >
+ (FMR_CHINA_HIGH_FREQ_IN_KHZ
+ * FMR_HRTZ_MULTIPLIER)) {
+ FM_ERR_REPORT("Invalid Freq "
+ "= %04x",
+ af_switch_freq);
+ } else {
+ status =
+ ste_fm_af_switch_start
+ (af_switch_freq,
+ af_switch_pi);
+ if (STE_STATUS_OK == status)
+ ret_val = 0;
+ }
+ }
+ }
+ break;
+ }
+ case V4L2_CID_RDS_TX_DEVIATION:
+ {
+ FM_DEBUG_REPORT("vidioc_set_ext_ctrls: "
+ "V4L2_CID_RDS_TX_DEVIATION, "
+ "Value = %d",
+ ext_ctrl->controls->value);
+ if (ext_ctrl->controls->value <= 0 &&
+ ext_ctrl->controls->value > 750) {
+ FM_ERR_REPORT("Invalid RDS Deviation = %02x",
+ ext_ctrl->controls->value);
+ } else {
+ status =
+ ste_fm_tx_set_rds_deviation(ext_ctrl->
+ controls->
+ value);
+ if (STE_STATUS_OK == status)
+ ret_val = 0;
+ }
+ break;
+ }
+ case V4L2_CID_RDS_TX_PI:
+ {
+ FM_DEBUG_REPORT("vidioc_set_ext_ctrls: "
+ "V4L2_CID_RDS_TX_PI, PI = %04x",
+ ext_ctrl->controls->value);
+ if (ext_ctrl->controls->value <= 0x0000 &&
+ ext_ctrl->controls->value > 0xFFFF) {
+ FM_ERR_REPORT("Invalid PI = %04x",
+ ext_ctrl->controls->value);
+ } else {
+ status =
+ ste_fm_tx_set_pi_code(ext_ctrl->controls->
+ value);
+ if (STE_STATUS_OK == status)
+ ret_val = 0;
+ }
+ break;
+ }
+ case V4L2_CID_RDS_TX_PTY:
+ {
+ FM_DEBUG_REPORT("vidioc_set_ext_ctrls: "
+ "V4L2_CID_RDS_TX_PTY, PTY = %d",
+ ext_ctrl->controls->value);
+ if (ext_ctrl->controls->value < 0 &&
+ ext_ctrl->controls->value > 31) {
+ FM_ERR_REPORT("Invalid PTY = %02x",
+ ext_ctrl->controls->value);
+ } else {
+ status =
+ ste_fm_tx_set_pty_code(ext_ctrl->controls->
+ value);
+ if (STE_STATUS_OK == status)
+ ret_val = 0;
+ }
+ break;
+ }
+ case V4L2_CID_RDS_TX_PS_NAME:
+ {
+ if (ext_ctrl->controls->size > MAX_PSN_SIZE
+ || ext_ctrl->controls->string == NULL) {
+ FM_ERR_REPORT("Invalid PSN");
+ } else {
+ FM_DEBUG_REPORT("vidioc_set_ext_ctrls: "
+ "V4L2_CID_RDS_TX_PS_NAME, "
+ "PSN = %s, Len = %d",
+ ext_ctrl->controls->string,
+ ext_ctrl->controls->size);
+
+ status =
+ ste_fm_tx_set_program_station_name
+ (ext_ctrl->controls->string,
+ ext_ctrl->controls->size);
+ if (STE_STATUS_OK == status)
+ ret_val = 0;
+ }
+ break;
+ }
+ case V4L2_CID_RDS_TX_RADIO_TEXT:
+ {
+ if (ext_ctrl->controls->size >= MAX_RT_SIZE
+ || ext_ctrl->controls->string == NULL) {
+ FM_ERR_REPORT("Invalid RT");
+ } else {
+ FM_DEBUG_REPORT("vidioc_set_ext_ctrls: "
+ "V4L2_CID_RDS_TX_RADIO_TEXT, "
+ "RT = %s, Len = %d",
+ ext_ctrl->controls->string,
+ ext_ctrl->controls->size);
+ status =
+ ste_fm_tx_set_radio_text(ext_ctrl->
+ controls->string,
+ ext_ctrl->
+ controls->size);
+ if (STE_STATUS_OK == status)
+ ret_val = 0;
+ }
+ break;
+ }
+ case V4L2_CID_PILOT_TONE_ENABLED:
+ {
+ bool enable;
+ FM_DEBUG_REPORT("vidioc_set_ext_ctrls: "
+ "V4L2_CID_PILOT_TONE_ENABLED, "
+ "Value = %d",
+ ext_ctrl->controls->value);
+ if (1 == ext_ctrl->controls->value) {
+ enable = true;
+ } else if (0 == ext_ctrl->controls->value) {
+ enable = false;
+ } else {
+ FM_ERR_REPORT("Unsupported Value = %d",
+ ext_ctrl->controls->value);
+ ret_val = -EINVAL;
+ goto err;
+ }
+ status = ste_fm_tx_set_pilot_tone_status(enable);
+ if (STE_STATUS_OK == status)
+ ret_val = 0;
+ break;
+ }
+ case V4L2_CID_PILOT_TONE_DEVIATION:
+ {
+ FM_DEBUG_REPORT("vidioc_set_ext_ctrls: "
+ "V4L2_CID_PILOT_TONE_DEVIATION, "
+ "Value = %d",
+ ext_ctrl->controls->value);
+ if (ext_ctrl->controls->value <= 0 &&
+ ext_ctrl->controls->value > 1000) {
+ FM_ERR_REPORT("Invalid Pilot Deviation = %02x",
+ ext_ctrl->controls->value);
+ } else {
+ status =
+ ste_fm_tx_set_pilot_deviation(ext_ctrl->
+ controls->
+ value);
+ if (STE_STATUS_OK == status)
+ ret_val = 0;
+ }
+ break;
+ }
+ case V4L2_CID_TUNE_PREEMPHASIS:
+ {
+ u8 preemphasis;
+ FM_DEBUG_REPORT("vidioc_set_ext_ctrls: "
+ "V4L2_CID_TUNE_PREEMPHASIS, "
+ "Value = %d",
+ ext_ctrl->controls->value);
+ if (V4L2_PREEMPHASIS_50_uS ==
+ ext_ctrl->controls->value) {
+ preemphasis = FMD_EMPHASIS_50US;
+ } else if (V4L2_PREEMPHASIS_75_uS ==
+ ext_ctrl->controls->value) {
+ preemphasis = FMD_EMPHASIS_75US;
+ } else {
+ FM_ERR_REPORT("Unsupported Preemphasis = %d",
+ ext_ctrl->controls->value);
+ ret_val = -EINVAL;
+ goto err;
+ }
+ status = ste_fm_tx_set_preemphasis(preemphasis);
+ if (STE_STATUS_OK == status)
+ ret_val = 0;
+ break;
+ }
+ case V4L2_CID_TUNE_POWER_LEVEL:
+ {
+ FM_DEBUG_REPORT("vidioc_set_ext_ctrls: "
+ "V4L2_CID_TUNE_POWER_LEVEL, "
+ "Value = %d",
+ ext_ctrl->controls->value);
+ if (ext_ctrl->controls->value <= 88 &&
+ ext_ctrl->controls->value > 123) {
+ FM_ERR_REPORT("Invalid Power Level = %02x",
+ ext_ctrl->controls->value);
+ } else {
+ status =
+ ste_fm_tx_set_power_level(ext_ctrl->
+ controls->value);
+ if (STE_STATUS_OK == status)
+ ret_val = 0;
+ }
break;
}
+ default:
+ {
+ FM_ERR_REPORT("vidioc_set_ext_ctrls: "
+ "Unsupported Id = %04x",
+ ext_ctrl->controls->id);
+ ret_val = -EINVAL;
+ }
}
- return -EINVAL;
+err:
+ return ret_val;
}
/**
- * vidioc_s_hw_freq_seek()- seek Up/Down Frequency.
+ * vidioc_set_hw_freq_seek()- seek Up/Down Frequency.
* This function is used to start seek
* on the FM Radio. Direction if seek is as inicated by the parameter
* inside the v4l2_hw_freq_seek structure. This function is called when the
* application issues the IOCTL VIDIOC_S_HW_FREQ_SEEK
*
- * @file: Pointer to the file structure
- * @priv: Pointer to the previous data of file structure.
- * @arg: Pointer to the v4l2_hw_freq_seek structure.
+ * @file: File structure.
+ * @priv: Previous data of file structure.
+ * @freq_seek: v4l2_hw_freq_seek structure.
*
* Returns:
* 0 when no error
* -EINVAL: otherwise
*/
-static int vidioc_s_hw_freq_seek(
- struct file *file,
- void *priv,
- struct v4l2_hw_freq_seek *arg
- )
+static int vidioc_set_hw_freq_seek(struct file *file,
+ void *priv,
+ struct v4l2_hw_freq_seek *freq_seek)
{
- struct v4l2_hw_freq_seek *seek = arg;
- uint8_t status;
-
- FM_DEBUG_REPORT("vidioc_s_hw_freq_seek");
- FM_DEBUG_REPORT("vidioc_s_hw_freq_seek: Status = %d, "\
- "Upwards = %d, Wrap Around = %d", \
- g_radio_cg2900_device->v_seekstatus,
- seek->seek_upward,
- seek->wrap_around);
- if (g_radio_cg2900_device->v_seekstatus == FMR_SEEK_IN_PROGRESS) {
- FM_DEBUG_REPORT("vidioc_s_hw_freq_seek: "\
- "VIDIOC_S_HW_FREQ_SEEK, "\
- "seek in progress");
+ u8 status;
+
+ FM_DEBUG_REPORT("vidioc_set_hw_freq_seek");
+ FM_DEBUG_REPORT("vidioc_set_hw_freq_seek: Status = %d, "
+ "Upwards = %d, Wrap Around = %d",
+ cg2900_device.v_seekstatus,
+ freq_seek->seek_upward, freq_seek->wrap_around);
+ if (cg2900_device.v_seekstatus == FMR_SEEK_IN_PROGRESS) {
+ FM_DEBUG_REPORT("vidioc_set_hw_freq_seek: "
+ "VIDIOC_S_HW_FREQ_SEEK, "
+ "freq_seek in progress");
return -EINVAL;
}
os_lock();
global_event = STE_EVENT_NO_EVENT;
- search_freq = 0;
- no_of_scanfreq = 0;
+ no_of_scan_freq = 0;
os_unlock();
- g_radio_cg2900_device->v_seekstatus = FMR_SEEK_IN_PROGRESS;
- if (1 == seek->seek_upward)
+ if (1 == freq_seek->seek_upward)
status = ste_fm_search_up_freq();
- else if (0 == seek->seek_upward)
+ else if (0 == freq_seek->seek_upward)
status = ste_fm_search_down_freq();
else
return -EINVAL;
- if (STE_STATUS_OK != status)
+ if (STE_STATUS_OK != status) {
return -EINVAL;
- else
+ } else {
+ cg2900_device.v_seekstatus = FMR_SEEK_IN_PROGRESS;
return 0;
+ }
}
/**
- * vidioc_g_audio()- Get Audio features of FM Driver.
+ * vidioc_get_audio()- Get Audio features of FM Driver.
* This function is used to get the audio features of FM Driver.
* This function is imlemented as a dumy function.
*
- * @file: Pointer to the file structure
- * @priv: Pointer to the previous data of file structure.
- * @arg: Pointer to the v4l2_audio structure.
+ * @file: File structure.
+ * @priv: Previous data of file structure.
+ * @audio: (out) v4l2_audio structure.
*
* Returns:
* 0 when no error
* -EINVAL: otherwise
*/
-static int vidioc_g_audio(
- struct file *file,
- void *priv,
- struct v4l2_audio *arg
- )
+static int vidioc_get_audio(struct file *file,
+ void *priv, struct v4l2_audio *audio)
{
- struct v4l2_audio *v = arg;
- FM_DEBUG_REPORT("vidioc_g_audio");
+ FM_DEBUG_REPORT("vidioc_get_audio");
- strcpy(v->name, ""); /* max. 16 bytes! */
- v->capability = 0;
- v->mode = 0;
+ strcpy(audio->name, "");
+ audio->capability = 0;
+ audio->mode = 0;
return 0;
}
/**
- * vidioc_s_audio()- Set Audio features of FM Driver.
+ * vidioc_set_audio()- Set Audio features of FM Driver.
* This function is used to set the audio features of FM Driver.
* This function is imlemented as a dumy function.
*
- * @file: Pointer to the file structure
- * @priv: Pointer to the previous data of file structure.
- * @arg: Pointer to the v4l2_audio structure.
+ * @file: File structure.
+ * @priv: Previous data of file structure.
+ * @audio: v4l2_audio structure.
*
* Returns:
* 0 when no error
* -EINVAL: otherwise
*/
-static int vidioc_s_audio(
- struct file *file,
- void *priv,
- struct v4l2_audio *arg
- )
+static int vidioc_set_audio(struct file *file,
+ void *priv, struct v4l2_audio *audio)
{
- FM_DEBUG_REPORT("vidioc_s_audio");
- if (arg->index != 0)
+ FM_DEBUG_REPORT("vidioc_set_audio");
+ if (audio->index != 0)
return -EINVAL;
return 0;
}
/**
- * vidioc_g_input()- Get the Input Value
+ * vidioc_get_input()- Get the Input Value
* This function is used to get the Input.
* This function is imlemented as a dumy function.
*
- * @file: Pointer to the file structure
- * @priv: Pointer to the previous data of file structure.
- * @i: Pointer to store the value.
+ * @file: File structure.
+ * @priv: Previous data of file structure.
+ * @input: (out) Value to be stored.
*
* Returns:
* 0 when no error
* -EINVAL: otherwise
*/
-static int vidioc_g_input(
- struct file *file,
- void *priv,
- unsigned int *i
- )
+static int vidioc_get_input(struct file *file, void *priv, unsigned int *input)
{
- FM_DEBUG_REPORT("vidioc_g_input");
- *i = 0;
+ FM_DEBUG_REPORT("vidioc_get_input");
+ *input = 0;
return 0;
}
/**
- * vidioc_s_input()- Set the input value.
+ * vidioc_set_input()- Set the input value.
* This function is used to set input.
* This function is imlemented as a dumy function.
*
- * @file: Pointer to the file structure
- * @priv: Pointer to the previous data of file structure.
- * @i: Value to set
+ * @file: File structure.
+ * @priv: Previous data of file structure.
+ * @input: Value to set
*
* Returns:
* 0 when no error
* -EINVAL: otherwise
*/
-static int vidioc_s_input(
- struct file *file,
- void *priv,
- unsigned int i
- )
+static int vidioc_set_input(struct file *file, void *priv, unsigned int input)
{
- FM_DEBUG_REPORT("vidioc_s_input");
- if (i != 0)
+ FM_DEBUG_REPORT("vidioc_set_input");
+ if (input != 0)
return -EINVAL;
return 0;
}
/**
- * radio_cg2900_convert_err_to_v4l2()- Convert Error Bits to V4L2 RDS format.
+ * cg2900_convert_err_to_v4l2()- Convert Error Bits to V4L2 RDS format.
* This function converts the error bits in RDS Block
* as received from Chip into V4L2 RDS data specification.
*
* @status_byte: The status byte as received in RDS Group for
* particular RDS Block
- * @out_byte: Pointer to the byte to store the modified byte with the err bits
+ * @out_byte: byte to store the modified byte with the err bits
* alligned as per V4L2 RDS Specifications.
*/
-static void radio_cg2900_convert_err_to_v4l2(
- char status_byte,
- char *out_byte
- )
+static void cg2900_convert_err_to_v4l2(char status_byte, char *out_byte)
{
- if ((status_byte & 0x03) == 0x03) {
+ if ((status_byte & RDS_ERROR_STATUS_MASK) == RDS_ERROR_STATUS_MASK) {
/* Uncorrectable Block */
*out_byte = (*out_byte | V4L2_RDS_BLOCK_ERROR);
- } else if (((status_byte & 0x01) == 0x01) ||
- ((status_byte & 0x02) == 0x02)) {
+ } else if (((status_byte & RDS_UPTO_TWO_BITS_CORRECTED)
+ == RDS_UPTO_TWO_BITS_CORRECTED) ||
+ ((status_byte & RDS_UPTO_FIVE_BITS_CORRECTED)
+ == RDS_UPTO_FIVE_BITS_CORRECTED)) {
/* Corrected Bits in Block */
*out_byte = (*out_byte | V4L2_RDS_BLOCK_CORRECTED);
}
}
/**
- * radio_cg2900_open()- This function nitializes and switches on FM.
+ * cg2900_open()- This function nitializes and switches on FM.
* This is called when the application opens the character device.
*
- * @file: Pointer to the file structure
+ * @file: File structure.
*
* Returns:
* 0 when no error
* -EINVAL: otherwise
*/
-static int radio_cg2900_open(
- struct file *file
- )
+static int cg2900_open(struct file *file)
{
- uint8_t status;
+ u8 status;
int ret_val = -EINVAL;
struct video_device *vdev = video_devdata(file);
lock_kernel();
users++;
- FM_DEBUG_REPORT("radio_cg2900_open: users = %d", users);
+ FM_DEBUG_REPORT("cg2900_open: users = %d", users);
if (users > 1) {
- FM_DEBUG_REPORT("radio_cg2900_open: FM already switched on!!!");
+ FM_INFO_REPORT("cg2900_open: FM already switched on!!!");
unlock_kernel();
- return -EINVAL;
+ return 0;
} else {
status = ste_fm_init();
if (STE_STATUS_OK == status) {
- FM_DEBUG_REPORT("radio_cg2900_open: Switching on FM");
- if (0 == band) {
- freq_low = 87.5 * STE_HRTZ_MULTIPLIER;
- freq_high = 108 * STE_HRTZ_MULTIPLIER;
- } else if (1 == band) {
- freq_low = 70 * STE_HRTZ_MULTIPLIER;
- freq_high = 108 * STE_HRTZ_MULTIPLIER;
- } else {
- freq_low = 76 * STE_HRTZ_MULTIPLIER;
- freq_high = 90 * STE_HRTZ_MULTIPLIER;
- }
- status = ste_fm_switch_on(
- &(vdev->dev),
- freq_low,
- band,
- grid);
+ FM_DEBUG_REPORT("cg2900_open: Switching on FM");
+ status = ste_fm_switch_on(&(vdev->dev));
if (STE_STATUS_OK == status) {
- g_radio_cg2900_device->v_state =
- FMR_SWITCH_ON;
- g_radio_cg2900_device->v_frequency =
- HZ_2_V4L2(freq_low);
- g_radio_cg2900_device->v_rds_enabled =
- STE_FALSE;
- g_radio_cg2900_device->v_muted =
- STE_FALSE;
- g_radio_cg2900_device->v_audiopath =
- 0;
- g_radio_cg2900_device->v_seekstatus =
- FMR_SEEK_NONE;
- g_radio_cg2900_device->v_rssi_threshold
- = STE_FM_DEFAULT_RSSI_THRESHOLD;
+ cg2900_device.v_state = FMR_SWITCH_ON;
+ cg2900_device.v_frequency =
+ HZ_TO_V4L2(freq_low);
+ cg2900_device.v_rx_rds_enabled = STE_FALSE;
+ cg2900_device.v_muted = STE_FALSE;
+ cg2900_device.v_audiopath = 0;
+ cg2900_device.v_seekstatus = FMR_SEEK_NONE;
+ cg2900_device.v_rssi_threshold
+ = STE_FM_DEFAULT_RSSI_THRESHOLD;
global_event = STE_EVENT_NO_EVENT;
- no_of_scanfreq = 0;
- ste_fm_set_rssi_threshold(
- g_radio_cg2900_device->v_rssi_threshold);
+ no_of_scan_freq = 0;
+ cg2900_device.v_fm_mode = STE_FM_IDLE_MODE;
ret_val = 0;
} else {
ste_fm_deinit();
@@ -1154,39 +1762,43 @@ static int radio_cg2900_open(
}
/**
- * radio_cg2900_release()- This function switches off FM.
+ * cg2900_release()- This function switches off FM.
* This function switches off FM and releases the resources.
* This is called when the application closes the character
* device.
*
- * @file: Pointer to the file structure
+ * @file: File structure.
*
* Returns:
* 0 when no error
* -EINVAL: otherwise
*/
-static int radio_cg2900_release(
- struct file *file
- )
+static int cg2900_release(struct file *file)
{
- uint8_t status;
+ u8 status;
int ret_val = -EINVAL;
- users--;
- FM_DEBUG_REPORT("radio_cg2900_release: users = %d", users);
+ if (users > 0) {
+ users--;
+ FM_DEBUG_REPORT("cg2900_release: users = %d", users);
+ } else {
+ FM_ERR_REPORT("cg2900_release: No users registered "
+ "with FM Driver");
+ return ret_val;
+ }
if (0 == users) {
- FM_DEBUG_REPORT("radio_cg2900_release: Switching Off FM");
+ FM_DEBUG_REPORT("cg2900_release: Switching Off FM");
status = ste_fm_switch_off();
status = ste_fm_deinit();
if (STE_STATUS_OK == status) {
- g_radio_cg2900_device->v_state = FMR_SWITCH_OFF;
- g_radio_cg2900_device->v_frequency = 0;
- g_radio_cg2900_device->v_rds_enabled = STE_FALSE;
- g_radio_cg2900_device->v_muted = STE_FALSE;
- g_radio_cg2900_device->v_seekstatus = FMR_SEEK_NONE;
+ cg2900_device.v_state = FMR_SWITCH_OFF;
+ cg2900_device.v_frequency = 0;
+ cg2900_device.v_rx_rds_enabled = STE_FALSE;
+ cg2900_device.v_muted = STE_FALSE;
+ cg2900_device.v_seekstatus = FMR_SEEK_NONE;
global_event = STE_EVENT_NO_EVENT;
- no_of_scanfreq = 0;
+ no_of_scan_freq = 0;
ret_val = 0;
}
}
@@ -1194,285 +1806,321 @@ static int radio_cg2900_release(
}
/**
- * radio_cg2900_read()- This function waits till RDS data is available.
- * This function is invoked when the application calls read() to receive
- * RDS Data.
+ * cg2900_read()- This function is invoked when the application
+ * calls read() to receive RDS Data.
*
- * @file: Pointer to the file structure
- * @data: Pointer to the buffer provided by application for receving the data.
+ * @file: File structure.
+ * @data: buffer provided by application for receving the data.
* @count: Number of bytes that application wants to read from driver
- * @pos: Pointer to the offset
+ * @pos: offset
*
* Returns:
* Number of bytes copied to the user buffer
* -EFAULT: If there is problem in copying data to buffer supplied
- * by application
+ * by application
* -EIO: If the number of bytes to be read are not a multiple of
- * struct v4l2_rds_data.
- * -EAGAIN: More than 22 blocks requested to be read.
+ * struct v4l2_rds_data.
+ * -EAGAIN: More than 22 blocks requested to be read or read
+ * was called in non blocking mode and no data was available for reading.
+ * -EINTR: If read was interrupted by a signal before data was avaialble.
* 0 when no data available for reading.
*/
-static ssize_t radio_cg2900_read(
- struct file *file,
- char __user *data,
- size_t count,
- loff_t *pos
- )
+static ssize_t cg2900_read(struct file *file,
+ char __user *data, size_t count, loff_t *pos)
{
int current_rds_grp;
int index = 0;
int blocks_to_read;
- struct v4l2_rds_data rdsbuf[MAX_RDS_GROUPS_READ * NUM_OF_RDS_BLOCKS];
- struct v4l2_rds_data *rdslocalbuf = rdsbuf;
+ int ret;
+ struct v4l2_rds_data rdsbuf[MAX_RDS_GROUPS * NUM_OF_RDS_BLOCKS];
+ struct v4l2_rds_data *rdslocalbuf = rdsbuf;
- FM_DEBUG_REPORT("radio_cg2900_read");
+ FM_DEBUG_REPORT("cg2900_read");
blocks_to_read = (count / sizeof(struct v4l2_rds_data));
if (count % sizeof(struct v4l2_rds_data) != 0) {
- FM_ERR_REPORT("radio_cg2900_read: Invalid Number of bytes %d "\
- "requested to read", count);
+ FM_ERR_REPORT("cg2900_read: Invalid Number of bytes %d "
+ "requested to read", count);
return -EIO;
}
- if (blocks_to_read > MAX_RDS_GROUPS_READ * NUM_OF_RDS_BLOCKS) {
- FM_ERR_REPORT("radio_cg2900_read: Too many blocks(%d) "\
- "requested to be read", blocks_to_read);
+ if (blocks_to_read > MAX_RDS_GROUPS * NUM_OF_RDS_BLOCKS) {
+ FM_ERR_REPORT("cg2900_read: Too many blocks(%d) "
+ "requested to be read", blocks_to_read);
return -EAGAIN;
}
- current_rds_grp = rds_group_sent;
- if ((g_radio_cg2900_device->v_rds_enabled) &&
- (head != tail) &&
- (ste_fm_rds_buf[tail][current_rds_grp].block1 != 0x0000)) {
+
+ if (file->f_flags & O_NONBLOCK) {
+ /* Non blocking mode selected by application */
+ if (ste_fm_rds_info.rds_head == ste_fm_rds_info.rds_tail) {
+ /* Check if data is available, else return */
+ FM_DEBUG_REPORT("cg2900_read: Non Blocking mode "
+ "selected by application, returning as "
+ "no RDS data is available");
+ return -EAGAIN;
+ }
+ } else if ((cg2900_device.v_rx_rds_enabled) &&
+ (ste_fm_rds_info.rds_head == ste_fm_rds_info.rds_tail)) {
+ /* Blocking mode selected by application
+ * if data is not available block on read queue */
+ FM_DEBUG_REPORT("cg2900_read: Blocking mode "
+ "selected by application, waiting till "
+ "rds data is available");
+ cg2900_device.v_waitonreadqueue = true;
+ ret = wait_event_interruptible(cg2900_read_queue,
+ (ste_fm_rds_info.rds_head !=
+ ste_fm_rds_info.rds_tail));
+ cg2900_device.v_waitonreadqueue = false;
+ FM_DEBUG_REPORT("cg2900_read: "
+ "wait_event_interruptible returned = %d", ret);
+ if (ret == -ERESTARTSYS)
+ return -EINTR;
+ }
+
+ current_rds_grp = ste_fm_rds_info.rds_group_sent;
+ if ((cg2900_device.v_rx_rds_enabled) &&
+ (ste_fm_rds_info.rds_head != ste_fm_rds_info.rds_tail) &&
+ (ste_fm_rds_buf[ste_fm_rds_info.rds_tail]
+ [current_rds_grp].block1 != 0x0000)) {
os_lock();
while (index < blocks_to_read) {
- switch (rds_block_sent % NUM_OF_RDS_BLOCKS) {
+ /* Check which Block needs to be transferred next */
+ switch (ste_fm_rds_info.rds_block_sent %
+ NUM_OF_RDS_BLOCKS) {
case 0:
- (rdslocalbuf + index)->lsb = \
- ste_fm_rds_buf[tail][current_rds_grp].block1;
- (rdslocalbuf + index)->msb = \
- ste_fm_rds_buf[tail][current_rds_grp].block1 >> 8;
- (rdslocalbuf + index)->block = \
- (ste_fm_rds_buf[tail][current_rds_grp].status1 & 0x1C) \
- >> 2;
- radio_cg2900_convert_err_to_v4l2(
- ste_fm_rds_buf[tail][current_rds_grp].status1,
- &(rdslocalbuf + index)->block);
- break;
+ (rdslocalbuf + index)->lsb =
+ ste_fm_rds_buf[ste_fm_rds_info.rds_tail]
+ [current_rds_grp].block1;
+ (rdslocalbuf + index)->msb =
+ ste_fm_rds_buf[ste_fm_rds_info.rds_tail]
+ [current_rds_grp].block1 >> 8;
+ (rdslocalbuf + index)->block =
+ (ste_fm_rds_buf[ste_fm_rds_info.rds_tail]
+ [current_rds_grp].status1
+ & RDS_BLOCK_MASK) >> 2;
+ cg2900_convert_err_to_v4l2(ste_fm_rds_buf
+ [ste_fm_rds_info.
+ rds_tail]
+ [current_rds_grp].
+ status1,
+ &(rdslocalbuf +
+ index)->block);
+ break;
case 1:
- (rdslocalbuf + index)->lsb = \
- ste_fm_rds_buf[tail][current_rds_grp].block2;
- (rdslocalbuf + index)->msb = \
- ste_fm_rds_buf[tail][current_rds_grp].block2 >> 8;
- (rdslocalbuf + index)->block = \
- (ste_fm_rds_buf[tail][current_rds_grp].status2 & 0x1C) \
- >> 2;
- radio_cg2900_convert_err_to_v4l2(
- ste_fm_rds_buf[tail][current_rds_grp].status2,
- &(rdslocalbuf + index)->block);
- break;
+ (rdslocalbuf + index)->lsb =
+ ste_fm_rds_buf[ste_fm_rds_info.rds_tail]
+ [current_rds_grp].block2;
+ (rdslocalbuf + index)->msb =
+ ste_fm_rds_buf[ste_fm_rds_info.rds_tail]
+ [current_rds_grp].block2 >> 8;
+ (rdslocalbuf + index)->block =
+ (ste_fm_rds_buf[ste_fm_rds_info.rds_tail]
+ [current_rds_grp].status2
+ & RDS_BLOCK_MASK) >> 2;
+ cg2900_convert_err_to_v4l2(ste_fm_rds_buf
+ [ste_fm_rds_info.
+ rds_tail]
+ [current_rds_grp].
+ status2,
+ &(rdslocalbuf +
+ index)->block);
+ break;
case 2:
- (rdslocalbuf + index)->lsb = \
- ste_fm_rds_buf[tail][current_rds_grp].block3;
- (rdslocalbuf + index)->msb = \
- ste_fm_rds_buf[tail][current_rds_grp].block3 >> 8;
- (rdslocalbuf + index)->block = \
- (ste_fm_rds_buf[tail][current_rds_grp].status3 & 0x1C) \
- >> 2;
- radio_cg2900_convert_err_to_v4l2(
- ste_fm_rds_buf[tail][current_rds_grp].status3,
- &(rdslocalbuf + index)->block);
- break;
+ (rdslocalbuf + index)->lsb =
+ ste_fm_rds_buf[ste_fm_rds_info.rds_tail]
+ [current_rds_grp].block3;
+ (rdslocalbuf + index)->msb =
+ ste_fm_rds_buf[ste_fm_rds_info.rds_tail]
+ [current_rds_grp].block3 >> 8;
+ (rdslocalbuf + index)->block =
+ (ste_fm_rds_buf[ste_fm_rds_info.rds_tail]
+ [current_rds_grp].status3
+ & RDS_BLOCK_MASK) >> 2;
+ cg2900_convert_err_to_v4l2(ste_fm_rds_buf
+ [ste_fm_rds_info.
+ rds_tail]
+ [current_rds_grp].
+ status3,
+ &(rdslocalbuf +
+ index)->block);
+ break;
case 3:
- (rdslocalbuf + index)->lsb = \
- ste_fm_rds_buf[tail][current_rds_grp].block4;
- (rdslocalbuf + index)->msb = \
- ste_fm_rds_buf[tail][current_rds_grp].block4 >> 8;
- (rdslocalbuf + index)->block = \
- (ste_fm_rds_buf[tail][current_rds_grp].status4 & 0x1C) \
- >> 2;
- radio_cg2900_convert_err_to_v4l2(
- ste_fm_rds_buf[tail][current_rds_grp].status4,
- &(rdslocalbuf + index)->block);
- current_rds_grp++;
- if (current_rds_grp == MAX_RDS_GROUPS_READ) {
- tail++;
- current_rds_grp = 0;
- }
- break;
+ (rdslocalbuf + index)->lsb =
+ ste_fm_rds_buf[ste_fm_rds_info.rds_tail]
+ [current_rds_grp].block4;
+ (rdslocalbuf + index)->msb =
+ ste_fm_rds_buf[ste_fm_rds_info.rds_tail]
+ [current_rds_grp].block4 >> 8;
+ (rdslocalbuf + index)->block =
+ (ste_fm_rds_buf[ste_fm_rds_info.rds_tail]
+ [current_rds_grp].status4
+ & RDS_BLOCK_MASK) >> 2;
+ cg2900_convert_err_to_v4l2(ste_fm_rds_buf
+ [ste_fm_rds_info.
+ rds_tail]
+ [current_rds_grp].
+ status4,
+ &(rdslocalbuf +
+ index)->block);
+ current_rds_grp++;
+ if (current_rds_grp == MAX_RDS_GROUPS) {
+ ste_fm_rds_info.rds_tail++;
+ current_rds_grp = 0;
+ }
+ break;
+ default:
+ FM_ERR_REPORT("Invalid RDS Group!!!");
+ os_unlock();
+ return 0;
}
/* FM_DEBUG_REPORT("%02x%02x %02x ",
- (rdslocalbuf + index)->msb, \
- (rdslocalbuf + index)->lsb, \
- (rdslocalbuf + index)->block); */
+ (rdslocalbuf + index)->msb, \
+ (rdslocalbuf + index)->lsb, \
+ (rdslocalbuf + index)->block); */
index++;
- rds_block_sent++;
- if (rds_block_sent == NUM_OF_RDS_BLOCKS)
- rds_block_sent = 0;
+ ste_fm_rds_info.rds_block_sent++;
+ if (ste_fm_rds_info.rds_block_sent == NUM_OF_RDS_BLOCKS)
+ ste_fm_rds_info.rds_block_sent = 0;
}
/* Update the RDS Group Count Sent to Application */
- rds_group_sent = current_rds_grp;
- if (tail == MAX_RDS_BUFFER)
- tail = 0;
+ ste_fm_rds_info.rds_group_sent = current_rds_grp;
+ if (ste_fm_rds_info.rds_tail == MAX_RDS_BUFFER)
+ ste_fm_rds_info.rds_tail = 0;
if (copy_to_user(data, rdslocalbuf, count)) {
os_unlock();
- FM_ERR_REPORT("radio_cg2900_read: Err "\
- "in copying, returning");
+ FM_ERR_REPORT("cg2900_read: Error "
+ "in copying, returning");
return -EFAULT;
}
os_unlock();
return count;
} else {
- FM_INFO_REPORT("radio_cg2900_read: returning 0");
+ FM_INFO_REPORT("cg2900_read: returning 0");
return 0;
}
}
/**
- * radio_cg2900_poll()- Check if the operation is compelte or not.
+ * cg2900_poll()- Check if the operation is complete or not.
* This function is invoked by application on calling poll() and is used to
- * wait till the desired operation seek/Band Scan are compelte.
+ * wait till the desired operation seek/Band Scan are complete.
* Driver blocks till the seek/BandScan Operation is complete. The application
* decides to read the results of seek/Band Scan based on the returned value of
* this function.
*
- * @file: Pointer to the file structure
- * @wait: Pointer to the poll table
+ * @file: File structure.
+ * @wait: poll table
*
* Returns:
* POLLRDBAND when Scan Band is complete and data is available for reading.
* POLLRDNORM when seek station is complete.
* POLLHUP when seek station/Band Scan is stopped by user using Stop Scan.
- * POLLERR when timeout occurs
*/
-static unsigned int radio_cg2900_poll(
- struct file *file,
- struct poll_table_struct *wait
- )
+
+static unsigned int cg2900_poll(struct file *file,
+ struct poll_table_struct *wait)
{
- uint8_t status;
- int ret;
- FM_DEBUG_REPORT("radio_cg2900_poll");
- ret = wait_event_interruptible_timeout(radio_cg2900_poll_queue,
- ((global_event == STE_EVENT_SCAN_CHANNELS_FOUND) ||
- (global_event == STE_EVENT_SEARCH_CHANNEL_FOUND) ||
- (global_event == STE_EVENT_NO_CHANNELS_FOUND)),
- timeval_to_jiffies(&max_scan_seek_time));
- FM_DEBUG_REPORT("+radio_cg2900_pol: Wait Ower, "\
- "v_seekstatus = %d, "\
- "global_event = %d",
- g_radio_cg2900_device->v_seekstatus,
- global_event);
-
- if (ret) {
- if (g_radio_cg2900_device->v_seekstatus ==
- FMR_SEEK_IN_PROGRESS) {
- if (global_event == STE_EVENT_SCAN_CHANNELS_FOUND) {
- /* Scan Completed, send event to application */
- return POLLRDBAND;
- } else if (global_event ==
- STE_EVENT_SEARCH_CHANNEL_FOUND) {
- uint32_t freq;
- /* Check to get Scan Result */
- status = ste_fm_get_frequency(&freq);
- FM_DEBUG_REPORT("radio_cg2900_poll: "\
- "New freq = %d Hz", freq);
- os_lock();
- search_freq = freq;
- os_unlock();
- /* seek Completed, send event to application */
- FM_DEBUG_REPORT("radio_cg2900_poll: "\
- "returning POLLRDNORM");
- return POLLRDNORM;
- }
+ FM_DEBUG_REPORT("cg2900_poll");
+
+ poll_wait(file, &cg2900_poll_queue, wait);
+ if (cg2900_device.v_seekstatus == FMR_SEEK_IN_PROGRESS) {
+ if ((global_event == STE_EVENT_SCAN_CHANNELS_FOUND) ||
+ (global_event == STE_EVENT_BLOCK_SCAN_CHANNELS_FOUND)) {
+ /* Scan Completed, send event to application */
+ FM_DEBUG_REPORT("poll_wait returning POLLRDBAND");
+ return POLLRDBAND;
+ } else if (global_event == STE_EVENT_SEARCH_CHANNEL_FOUND) {
+ FM_DEBUG_REPORT("cg2900_poll: " "returning POLLRDNORM");
+ FM_DEBUG_REPORT("poll_wait returning POLLRDNORM");
+ return POLLRDNORM;
+ } else if (global_event == STE_EVENT_SCAN_CANCELLED) {
+ /* Scan/Search cancelled by User */
+ os_lock();
+ no_of_scan_freq = 0;
+ no_of_block_scan_freq = 0;
+ os_unlock();
+ cg2900_device.v_seekstatus = FMR_SEEK_NONE;
+ global_event = STE_EVENT_NO_EVENT;
+ FM_DEBUG_REPORT("cg2900_poll: "
+ "Cancel operation "
+ "returning POLLHUP");
+ FM_DEBUG_REPORT("poll_wait returning POLLHUP");
+ return POLLHUP;
}
- /* Scan/Search cancelled by User */
- os_lock();
- no_of_scanfreq = 0;
- os_unlock();
- g_radio_cg2900_device->v_seekstatus = FMR_SEEK_NONE;
- global_event = STE_EVENT_NO_EVENT;
- FM_DEBUG_REPORT("radio_cg2900_poll: Cancel operation "\
- "returning POLLHUP");
- return POLLHUP;
- } else {
- /* Timeout */
- os_lock();
- no_of_scanfreq = 0;
- os_unlock();
- g_radio_cg2900_device->v_seekstatus = FMR_SEEK_NONE;
- global_event = STE_EVENT_NO_EVENT;
- FM_ERR_REPORT("radio_cg2900_poll: Timeout: returning POLLERR");
- return POLLERR;
}
+ FM_DEBUG_REPORT("poll_wait returning 0");
+ return 0;
+
}
/**
- * radio_cg2900_init()- This function initializes the FM Driver.
+ * cg2900_init()- This function initializes the FM Driver.
* This Fucntion is called whenever the Driver is loaded from
- * VideoForLinux driver. It registers the FM Driver with Video4Linux
+ * Video4Linux driver. It registers the FM Driver with Video4Linux
* as a character device.
*
* Returns:
* 0 on success
* -EINVAL on error
*/
-static int __init radio_cg2900_init(void)
+static int __init cg2900_init(void)
{
FM_INFO_REPORT(BANNER);
- FM_DEBUG_REPORT("radio_cg2900_init: radio_nr= %d.", radio_nr);
- /* Initialize the parameters */
radio_nr = 0;
grid = 1;
band = 0;
- if (video_register_device(&radio_cg2900_video_device, \
- VFL_TYPE_RADIO, radio_nr) == -1) {
- FM_ERR_REPORT("radio_cg2900_init: video_register_device err");
+ FM_DEBUG_REPORT("cg2900_init: radio_nr= %d.", radio_nr);
+ /* Initialize the parameters */
+ if (video_register_device(&cg2900_video_device,
+ VFL_TYPE_RADIO, radio_nr) == -1) {
+ FM_ERR_REPORT("cg2900_init: video_register_device err");
return -EINVAL;
}
+ init_waitqueue_head(&cg2900_poll_queue);
users = 0;
return 0;
}
/**
- * radio_cg2900_deinit()- This function deinitializes the FM Driver.
+ * cg2900_deinit()- This function deinitializes the FM Driver.
* This Fucntion is called whenever the Driver is unloaded from
* VideoForLinux driver.
*/
-static void __exit radio_cg2900_deinit(void)
+static void __exit cg2900_exit(void)
{
- FM_INFO_REPORT("radio_cg2900_deinit");
+ FM_INFO_REPORT("cg2900_exit");
/* Try to Switch Off FM in case it is still switched on */
ste_fm_switch_off();
ste_fm_deinit();
- video_unregister_device(&radio_cg2900_video_device);
+ video_unregister_device(&cg2900_video_device);
}
/* ------------------ External Function definitions ---------------------- */
void wake_up_poll_queue(void)
{
FM_DEBUG_REPORT("wake_up_poll_queue");
- wake_up_interruptible(&radio_cg2900_poll_queue);
+ wake_up_interruptible(&cg2900_poll_queue);
}
-module_init(radio_cg2900_init);
-module_exit(radio_cg2900_deinit);
+void wake_up_read_queue(void)
+{
+ FM_DEBUG_REPORT("wake_up_read_queue");
+ if (cg2900_device.v_waitonreadqueue)
+ wake_up_interruptible(&cg2900_read_queue);
+}
+
+module_init(cg2900_init);
+module_exit(cg2900_exit);
MODULE_AUTHOR("Hemant Gupta");
MODULE_LICENSE("GPL v2");
module_param(radio_nr, int, S_IRUGO);
module_param(grid, int, S_IRUGO | S_IWUSR | S_IWGRP);
-MODULE_PARM_DESC(grid, "Grid:"\
- "0=200 kHz"\
- "*1=100 kHz*"\
- "2=50k Hz");
+MODULE_PARM_DESC(grid, "Grid:" "0=50 kHz" "*1=100 kHz*" "2=200 kHz");
module_param(band, int, S_IRUGO | S_IWUSR | S_IWGRP);
-MODULE_PARM_DESC(band, "Band:"\
- "*0=87.5-108 MHz*"\
- "1=70-108 MHz"\
- "2=76-90 MHz");
-
+MODULE_PARM_DESC(band, "Band:" "*0=87.5-108 MHz*" "1=76-90 MHz" "2=70-108 MHz");
diff --git a/drivers/media/radio/CG2900/stefmapi.c b/drivers/media/radio/CG2900/stefmapi.c
index a854de0672d..a0d2b9cb5da 100755
--- a/drivers/media/radio/CG2900/stefmapi.c
+++ b/drivers/media/radio/CG2900/stefmapi.c
@@ -1,6 +1,4 @@
/*
- * file stefmapi.c
- *
* Copyright (C) ST-Ericsson SA 2010
*
* Linux FM Host API's for ST-Ericsson FM Chip.
@@ -24,59 +22,51 @@
#define STE_FM_FM_PROG_INFO_FILE "ste_fm_fm_prog_info.fw"
#define STE_FM_LINE_BUFFER_LENGTH 128
#define STE_FM_FILENAME_MAX 128
+/* RDS Tx PTY set to Other music */
+#define OTHER_MUSIC 15
-static uint16_t vol_index;
-static bool fm_init;
-static bool fm_power_on;
-static bool fm_stand_by;
-static bool fm_rds_status;
-static bool fm_prev_rds_status;
+static bool fm_rds_status;
+static bool fm_prev_rds_status;
static void *context;
-static uint8_t gfreq_range = FMD_FREQRANGE_FMEUROAMERICA;
-static struct mutex rds_mutex;
-
-uint8_t global_event;
-uint8_t head;
-uint8_t tail;
-uint8_t rds_group_sent;
-uint8_t rds_block_sent;
-struct ste_fm_rds_buf_s ste_fm_rds_buf[MAX_RDS_BUFFER][MAX_RDS_GROUPS_READ];
-
-static uint32_t hci_revision = 0x0700;
-static uint32_t lmp_sub_version = 0x0011;
+/* hci revision and lmp sub version is hardcoded for the moment
+ * as get version cmd does not work before firmware download */
+static u32 hci_revision = 0x0700;
+static u32 lmp_sub_version = 0x0011;
+static u16 program_identification_code;
+static u16 default_program_identification_code = 0x1234;
+static u16 program_type_code;
+static u16 default_program_type_code = OTHER_MUSIC;
+static char program_service[MAX_PSN_SIZE];
+static char default_program_service[MAX_PSN_SIZE] = "FM-Xmit ";
+static char radio_text[MAX_RT_SIZE];
+static char default_radio_text[MAX_RT_SIZE] = "Default Radio Text "
+ "Default Radio Text Default Radio Text Default";
+static bool a_b_flag = STE_FALSE;
+static struct mutex rds_mutex;
+struct ste_fm_rds_buf_t ste_fm_rds_buf[MAX_RDS_BUFFER][MAX_RDS_GROUPS];
+struct ste_fm_rds_info_t ste_fm_rds_info;
+static enum ste_fm_state_t ste_fm_state;
+static enum ste_fm_mode_t ste_fm_mode;
+u8 global_event;
/* ------------------ Internal function declarations ---------------------- */
-static const char *str_stestatus(
- uint8_t status
- );
-static void ste_fm_driver_callback(
- void *context,
- uint32_t event,
- uint32_t event_int_data,
- bool event_boolean_data
- );
+static char *ste_fm_get_one_line_of_text(char *wr_buffer,
+ int max_nbr_of_bytes,
+ char *rd_buffer, int *bytes_copied);
+static bool ste_fm_get_file_to_load(const struct firmware *fw,
+ char **file_name);
+static u8 ste_fm_load_firmware(struct device *device);
+static u8 ste_fm_transmit_rds_groups(void);
+static void ste_fm_driver_callback(void *context,
+ u8 event, bool event_successful);
static void ste_fm_rds_callback(void);
-static char *ste_fm_get_one_line_of_text(
- char *wr_buffer,
- int max_nbr_of_bytes,
- char *rd_buffer,
- int *bytes_copied
- );
-static bool ste_fm_get_file_to_load(
- const struct firmware *fw,
- char **file_name
- );
-static uint8_t ste_fm_load_firmware(
- struct device *device
- );
-
+static const char *str_stestatus(u8 status);
/* ------------------ Internal function definitions ---------------------- */
/**
- * ste_fm_get_one_line_of_text()- Replacement function for stdio
- * function fgets.
- * The ste_fm_get_one_line_of_text() function extracts one line of text
- * from input file.
+ * ste_fm_get_one_line_of_text()- Get One line of text from a file.
+ * Replacement function for stdio function fgets.This function extracts one
+ * line of text from input file.
* @wr_buffer: Buffer to copy text to.
* @max_nbr_of_bytes: Max number of bytes to read, i.e. size of rd_buffer.
* @rd_buffer: Data to parse.
@@ -85,12 +75,9 @@ static uint8_t ste_fm_load_firmware(
* Returns:
* Pointer to next data to read.
*/
-static char *ste_fm_get_one_line_of_text(
- char *wr_buffer,
- int max_nbr_of_bytes,
- char *rd_buffer,
- int *bytes_copied
- )
+static char *ste_fm_get_one_line_of_text(char *wr_buffer,
+ int max_nbr_of_bytes,
+ char *rd_buffer, int *bytes_copied)
{
char *curr_wr = wr_buffer;
char *curr_rd = rd_buffer;
@@ -105,7 +92,7 @@ static char *ste_fm_get_one_line_of_text(
curr_rd++;
(*bytes_copied)++;
} while ((*bytes_copied <= max_nbr_of_bytes) && (in_byte != '\0')
- && (in_byte != '\n'));
+ && (in_byte != '\n'));
*curr_wr = '\0';
return curr_rd;
}
@@ -119,10 +106,7 @@ static char *ste_fm_get_one_line_of_text(
* True, if target file was found,
* False, otherwise.
*/
-static bool ste_fm_get_file_to_load(
- const struct firmware *fw,
- char **file_name
- )
+static bool ste_fm_get_file_to_load(const struct firmware *fw, char **file_name)
{
char *line_buffer;
char *curr_file_buffer;
@@ -132,34 +116,36 @@ static bool ste_fm_get_file_to_load(
curr_file_buffer = (char *)&(fw->data[0]);
- line_buffer = kzalloc(STE_FM_LINE_BUFFER_LENGTH, GFP_KERNEL);
+ line_buffer = os_mem_alloc(STE_FM_LINE_BUFFER_LENGTH);
if (line_buffer) {
while (!file_found) {
/* Get one line of text from the file to parse */
- curr_file_buffer = \
- ste_fm_get_one_line_of_text(line_buffer,
- min(STE_FM_LINE_BUFFER_LENGTH,
- (int)(fw->size - bytes_read)),
- curr_file_buffer,
- &bytes_read);
+ curr_file_buffer =
+ ste_fm_get_one_line_of_text(line_buffer,
+ min
+ (STE_FM_LINE_BUFFER_LENGTH,
+ (int)(fw->size -
+ bytes_read)),
+ curr_file_buffer,
+ &bytes_read);
bytes_left_to_parse -= bytes_read;
if (bytes_left_to_parse <= 0) {
/* End of file => Leave while loop */
- FM_ERR_REPORT("Reached end of file." \
- "No file found!");
+ FM_ERR_REPORT("Reached end of file."
+ "No file found!");
break;
}
/* Check if the line of text is a comment
* or not, comments begin with '#' */
if (*line_buffer != '#') {
- uint32_t hci_rev = 0;
- uint32_t lmp_sub = 0;
+ u32 hci_rev = 0;
+ u32 lmp_sub = 0;
FM_DEBUG_REPORT("Found a valid line <%s>",
- line_buffer);
+ line_buffer);
/* Check if we can find the correct
* HCI revision and LMP subversion
@@ -168,38 +154,37 @@ static bool ste_fm_get_file_to_load(
* be found in the file system
*/
if (sscanf(line_buffer, "%x%x%s",
- (unsigned int *)&hci_rev, \
- (unsigned int *)&lmp_sub,
- *file_name) == 3 \
- && hci_rev == hci_revision
- && lmp_sub == lmp_sub_version) {
- FM_INFO_REPORT(\
- "File name = %s " \
- "HCI Revision" \
- "= 0x%X LMP PAL" \
- "Subversion = 0x%X", \
- *file_name,
- (unsigned int)hci_rev,
- (unsigned int)lmp_sub);
-
- /* Name has already
- * been stored above.
- * Nothing more to do */
- file_found = true;
+ (unsigned int *)&hci_rev,
+ (unsigned int *)&lmp_sub,
+ *file_name) == 3
+ && hci_rev == hci_revision
+ && lmp_sub == lmp_sub_version) {
+ FM_INFO_REPORT("File name = %s "
+ "HCI Revision"
+ "= 0x%X LMP PAL"
+ "Subversion = 0x%X",
+ *file_name,
+ (unsigned int)hci_rev,
+ (unsigned int)lmp_sub);
+
+ /* Name has already
+ * been stored above.
+ * Nothing more to do */
+ file_found = true;
} else {
/* Zero the name buffer so
* it is clear to next read */
memset(*file_name, 0x00,
- STE_FM_FILENAME_MAX + 1);
+ STE_FM_FILENAME_MAX);
}
}
}
- kfree(line_buffer);
+ os_mem_free(line_buffer);
} else {
- FM_ERR_REPORT("Failed to allocate:" \
- "file_name 0x%X, line_buffer 0x%X",
- (unsigned int)file_name,
- (unsigned int)line_buffer);
+ FM_ERR_REPORT("Failed to allocate:"
+ "file_name 0x%X, line_buffer 0x%X",
+ (unsigned int)file_name,
+ (unsigned int)line_buffer);
}
return file_found;
@@ -210,16 +195,14 @@ static bool ste_fm_get_file_to_load(
* @device: Pointer to char device requesting the operation.
*
* Returns:
- * STE_STATUS_OK, if firmware donload is successful
+ * STE_STATUS_OK, if firmware download is successful
* STE_STATUS_SYSTEM_ERROR, otherwise.
*/
-static uint8_t ste_fm_load_firmware(
- struct device *device
- )
+static u8 ste_fm_load_firmware(struct device *device)
{
int err = 0;
bool file_found;
- uint8_t result = STE_STATUS_OK;
+ u8 result = STE_STATUS_OK;
const struct firmware *bt_src_coeff_info;
const struct firmware *ext_src_coeff_info;
const struct firmware *fm_coeff_info;
@@ -233,215 +216,353 @@ static uint8_t ste_fm_load_firmware(
/* Open bt_src_coeff info file. */
err = request_firmware(&bt_src_coeff_info,
- STE_FM_BT_SRC_COEFF_INFO_FILE, device);
+ STE_FM_BT_SRC_COEFF_INFO_FILE, device);
if (err) {
- FM_ERR_REPORT("Couldn't get bt_src_coeff info file");
- result = STE_STATUS_SYSTEM_ERROR;
- goto error_handling;
+ FM_ERR_REPORT("ste_fm_load_firmware: "
+ "Couldn't get bt_src_coeff info file");
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
/* Now we have the bt_src_coeff info file.
* See if we can find the right bt_src_coeff file as well */
bt_src_coeff_file_name = os_mem_alloc(STE_FM_FILENAME_MAX);
- file_found = ste_fm_get_file_to_load(bt_src_coeff_info,
- &bt_src_coeff_file_name);
+ if (bt_src_coeff_file_name != NULL) {
+ file_found = ste_fm_get_file_to_load(bt_src_coeff_info,
+ &bt_src_coeff_file_name);
- /* Now we are finished with the bt_src_coeff info file */
- release_firmware(bt_src_coeff_info);
+ /* Now we are finished with the bt_src_coeff info file */
+ release_firmware(bt_src_coeff_info);
- if (!file_found) {
- FM_ERR_REPORT("Couldn't find bt_src_coeff file! Major error!");
- result = STE_STATUS_SYSTEM_ERROR;
- goto error_handling;
+ if (!file_found) {
+ FM_ERR_REPORT("ste_fm_load_firmware: "
+ "Couldn't find bt_src_coeff file!! "
+ "Major error!!!");
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
+ } else {
+ FM_ERR_REPORT("ste_fm_load_firmware: "
+ "Couldn't allocate memory for "
+ "bt_src_coeff_file_name");
+ release_firmware(bt_src_coeff_info);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
/* Open ext_src_coeff info file. */
err = request_firmware(&ext_src_coeff_info,
- STE_FM_EXT_SRC_COEFF_INFO_FILE, device);
+ STE_FM_EXT_SRC_COEFF_INFO_FILE, device);
if (err) {
- FM_ERR_REPORT("Couldn't get ext_src_coeff_info info file");
- result = STE_STATUS_SYSTEM_ERROR;
- goto error_handling;
+ FM_ERR_REPORT("ste_fm_load_firmware: "
+ "Couldn't get ext_src_coeff_info info file");
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
/* Now we have the ext_src_coeff info file. See if we can
* find the right ext_src_coeff file as well */
ext_src_coeff_file_name = os_mem_alloc(STE_FM_FILENAME_MAX);
- file_found = ste_fm_get_file_to_load(ext_src_coeff_info,
- &ext_src_coeff_file_name);
+ if (ext_src_coeff_file_name != NULL) {
+ file_found = ste_fm_get_file_to_load(ext_src_coeff_info,
+ &ext_src_coeff_file_name);
- /* Now we are finished with the ext_src_coeff info file */
- release_firmware(ext_src_coeff_info);
+ /* Now we are finished with the ext_src_coeff info file */
+ release_firmware(ext_src_coeff_info);
- if (!file_found) {
- FM_ERR_REPORT("Couldn't find ext_src_coeff_info "\
- "file! Major error!");
- result = STE_STATUS_SYSTEM_ERROR;
- goto error_handling;
+ if (!file_found) {
+ FM_ERR_REPORT("ste_fm_load_firmware: "
+ "Couldn't find ext_src_coeff_info "
+ "file!!! Major error!");
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
+ } else {
+ FM_ERR_REPORT("ste_fm_load_firmware: "
+ "Couldn't allocate memory for "
+ "ext_src_coeff_file_name");
+ release_firmware(ext_src_coeff_info);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
/* Open fm_coeff info file. */
err = request_firmware(&fm_coeff_info,
- STE_FM_FM_COEFF_INFO_FILE, device);
+ STE_FM_FM_COEFF_INFO_FILE, device);
if (err) {
- FM_ERR_REPORT("Couldn't get fm_coeff info file");
- result = STE_STATUS_SYSTEM_ERROR;
- goto error_handling;
+ FM_ERR_REPORT("ste_fm_load_firmware: "
+ "Couldn't get fm_coeff info file");
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
/* Now we have the fm_coeff_info info file.
* See if we can find the right fm_coeff_info file as well */
fm_coeff_file_name = os_mem_alloc(STE_FM_FILENAME_MAX);
- file_found = ste_fm_get_file_to_load(fm_coeff_info,
- &fm_coeff_file_name);
+ if (fm_coeff_file_name != NULL) {
+ file_found = ste_fm_get_file_to_load(fm_coeff_info,
+ &fm_coeff_file_name);
- /* Now we are finished with the fm_coeff info file */
- release_firmware(fm_coeff_info);
+ /* Now we are finished with the fm_coeff info file */
+ release_firmware(fm_coeff_info);
- if (!file_found) {
- FM_ERR_REPORT("Couldn't find fm_coeff file! Major error!");
- result = STE_STATUS_SYSTEM_ERROR;
- goto error_handling;
+ if (!file_found) {
+ FM_ERR_REPORT("ste_fm_load_firmware: "
+ "Couldn't find fm_coeff file!!! "
+ "Major error!");
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
+ } else {
+ FM_ERR_REPORT("ste_fm_load_firmware: "
+ "Couldn't allocate memory for "
+ "fm_coeff_file_name");
+ release_firmware(fm_coeff_info);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
/* Open fm_prog info file. */
- err = request_firmware(&fm_prog_info,
- STE_FM_FM_PROG_INFO_FILE, device);
+ err = request_firmware(&fm_prog_info, STE_FM_FM_PROG_INFO_FILE, device);
if (err) {
- FM_ERR_REPORT("Couldn't get fm_prog_info info file");
- result = STE_STATUS_SYSTEM_ERROR;
- goto error_handling;
+ FM_ERR_REPORT("ste_fm_load_firmware: "
+ "Couldn't get fm_prog_info info file");
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
/* Now we have the fm_prog info file.
* See if we can find the right fm_prog file as well
*/
fm_prog_file_name = os_mem_alloc(STE_FM_FILENAME_MAX);
- file_found = ste_fm_get_file_to_load(fm_prog_info,
- &fm_prog_file_name);
+ if (fm_prog_file_name != NULL) {
+ file_found = ste_fm_get_file_to_load(fm_prog_info,
+ &fm_prog_file_name);
- /* Now we are finished with fm_prog patch info file */
- release_firmware(fm_prog_info);
+ /* Now we are finished with fm_prog patch info file */
+ release_firmware(fm_prog_info);
- if (!file_found) {
- FM_ERR_REPORT("Couldn't find fm_prog_info file! Major error!");
- result = STE_STATUS_SYSTEM_ERROR;
- goto error_handling;
+ if (!file_found) {
+ FM_ERR_REPORT("ste_fm_load_firmware: "
+ "Couldn't find fm_prog_info file!!! "
+ "Major error!");
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
+ } else {
+ FM_ERR_REPORT("ste_fm_load_firmware: "
+ "Couldn't allocate memory for "
+ "fm_prog_file_name");
+ release_firmware(fm_prog_info);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
/* OK. Now it is time to download the firmware */
err = request_firmware(&bt_src_coeff_info,
- bt_src_coeff_file_name, device);
+ bt_src_coeff_file_name, device);
if (err < 0) {
- FM_ERR_REPORT("Couldn't get bt_src_coeff file, err = %d", err);
- result = STE_STATUS_SYSTEM_ERROR;
- goto error_handling;
+ FM_ERR_REPORT("ste_fm_load_firmware: "
+ "Couldn't get bt_src_coeff file, err = %d", err);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
FM_INFO_REPORT("ste_fm_load_firmware: Downloading %s of %d bytes",
- bt_src_coeff_file_name, bt_src_coeff_info->size);
- if (fmd_send_fm_firmware((uint8_t *)bt_src_coeff_info->data,
- bt_src_coeff_info->size)) {
+ bt_src_coeff_file_name, bt_src_coeff_info->size);
+ if (fmd_send_fm_firmware((u8 *) bt_src_coeff_info->data,
+ bt_src_coeff_info->size)) {
FM_ERR_REPORT("ste_fm_load_firmware: Error in downloading %s",
- bt_src_coeff_file_name);
- result = STE_STATUS_SYSTEM_ERROR;
- goto error_handling;
+ bt_src_coeff_file_name);
+ release_firmware(bt_src_coeff_info);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
/* Now we are finished with the bt_src_coeff info file */
release_firmware(bt_src_coeff_info);
- os_mem_free(bt_src_coeff_file_name);
-
err = request_firmware(&ext_src_coeff_info,
- ext_src_coeff_file_name, device);
+ ext_src_coeff_file_name, device);
if (err < 0) {
- FM_ERR_REPORT("Couldn't get ext_src_coeff file, err = %d", err)
- goto error_handling;
+ FM_ERR_REPORT("ste_fm_load_firmware: "
+ "Couldn't get ext_src_coeff file, err = %d", err);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
FM_INFO_REPORT("ste_fm_load_firmware: Downloading %s of %d bytes",
- ext_src_coeff_file_name, ext_src_coeff_info->size);
- if (fmd_send_fm_firmware((uint8_t *)ext_src_coeff_info->data,
- ext_src_coeff_info->size)) {
+ ext_src_coeff_file_name, ext_src_coeff_info->size);
+ if (fmd_send_fm_firmware((u8 *) ext_src_coeff_info->data,
+ ext_src_coeff_info->size)) {
FM_ERR_REPORT("ste_fm_load_firmware: Error in downloading %s",
- ext_src_coeff_file_name);
- result = STE_STATUS_SYSTEM_ERROR;
- goto error_handling;
+ ext_src_coeff_file_name);
+ release_firmware(ext_src_coeff_info);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
/* Now we are finished with the bt_src_coeff info file */
release_firmware(ext_src_coeff_info);
- os_mem_free(ext_src_coeff_file_name);
- err = request_firmware(&fm_coeff_info,
- fm_coeff_file_name, device);
+ err = request_firmware(&fm_coeff_info, fm_coeff_file_name, device);
if (err < 0) {
- FM_ERR_REPORT("Couldn't get fm_coeff file, err = %d", err)
- goto error_handling;
+ FM_ERR_REPORT("ste_fm_load_firmware: "
+ "Couldn't get fm_coeff file, err = %d", err);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
FM_INFO_REPORT("ste_fm_load_firmware: Downloading %s of %d bytes",
- fm_coeff_file_name, fm_coeff_info->size);
- if (fmd_send_fm_firmware((uint8_t *)fm_coeff_info->data,
- fm_coeff_info->size)) {
+ fm_coeff_file_name, fm_coeff_info->size);
+ if (fmd_send_fm_firmware((u8 *) fm_coeff_info->data,
+ fm_coeff_info->size)) {
FM_ERR_REPORT("ste_fm_load_firmware: Error in downloading %s",
- fm_coeff_file_name);
- result = STE_STATUS_SYSTEM_ERROR;
- goto error_handling;
+ fm_coeff_file_name);
+ release_firmware(fm_coeff_info);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
/* Now we are finished with the bt_src_coeff info file */
release_firmware(fm_coeff_info);
- os_mem_free(fm_coeff_file_name);
err = request_firmware(&fm_prog_info, fm_prog_file_name, device);
if (err < 0) {
- FM_ERR_REPORT("Couldn't get fm_prog file, err = %d", err)
- goto error_handling;
+ FM_ERR_REPORT("ste_fm_load_firmware: "
+ "Couldn't get fm_prog file, err = %d", err);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
FM_INFO_REPORT("ste_fm_load_firmware: Downloading %s of %d bytes",
- fm_prog_file_name, fm_prog_info->size);
- if (fmd_send_fm_firmware((uint8_t *)fm_prog_info->data,
+ fm_prog_file_name, fm_prog_info->size);
+ if (fmd_send_fm_firmware((u8 *) fm_prog_info->data,
fm_prog_info->size)) {
FM_ERR_REPORT("ste_fm_load_firmware: Error in downloading %s",
- fm_prog_file_name);
- result = STE_STATUS_SYSTEM_ERROR;
- goto error_handling;
+ fm_prog_file_name);
+ release_firmware(fm_prog_info);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
/* Now we are finished with the bt_src_coeff info file */
release_firmware(fm_prog_info);
- os_mem_free(fm_prog_file_name);
-error_handling:
- FM_DEBUG_REPORT("-ste_fm_load_firmware returning = %d", result);
+error:
+ /* Free Allocated memory, NULL checking done inside resp functions */
+ os_mem_free(bt_src_coeff_file_name);
+ os_mem_free(ext_src_coeff_file_name);
+ os_mem_free(fm_coeff_file_name);
+ os_mem_free(fm_prog_file_name);
+ FM_DEBUG_REPORT("-ste_fm_load_firmware: returning %s",
+ str_stestatus(result));
return result;
}
/**
- * str_stestatus()- Returns the status value as a printable string.
- * @status: Status
+ * ste_fm_transmit_rds_groups()- Transmits the RDS Groups.
+ * Stores the RDS Groups in Chip's buffer and each group is
+ * transmitted every 87.6 ms.
*
* Returns:
- * Pointer to a string containing printable value of status
+ * STE_STATUS_OK, if operation completed successfully.
+ * STE_STATUS_SYSTEM_ERROR, otherwise.
*/
-static const char *str_stestatus(
- uint8_t status
- )
+static u8 ste_fm_transmit_rds_groups(void)
{
- switch (status) {
- case STE_STATUS_OK:
- return "STE_STATUS_OK";
- case STE_STATUS_SYSTEM_ERROR:
- return "STE_STATUS_SYSTEM_ERROR";
- case STE_STATUS_SEARCH_NO_CHANNEL_FOUND:
- return "STE_STATUS_SEARCH_NO_CHANNEL_FOUND";
- case STE_STATUS_SCAN_NO_CHANNEL_FOUND:
- return "STE_STATUS_SCAN_NO_CHANNEL_FOUND";
- default:
- return "Unknown status";
+ u8 result = STE_STATUS_OK;
+ u16 group_position = 0;
+ u8 block1[2];
+ u8 block2[2];
+ u8 block3[2];
+ u8 block4[2];
+ int index1 = 0;
+ int index2 = 0;
+ int group_0B_count = 0;
+ int group_2A_count = 0;
+
+ FM_INFO_REPORT("ste_fm_transmit_rds_groups");
+
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+ while (group_position < 20 && result == STE_STATUS_OK) {
+ if (group_position < 4) {
+ /* Transmit PSN in Group 0B */
+ block1[0] = program_identification_code;
+ block1[1] = program_identification_code >> 8;
+ /* M/S bit set to Music */
+ if (group_0B_count % 4 == 0) {
+ /* Manipulate DI bit */
+ block2[0] =
+ (0x08 | ((program_type_code & 0x07)
+ << 5))
+ + group_0B_count;
+ } else {
+ block2[0] =
+ (0x0C | ((program_type_code & 0x07)
+ << 5))
+ + group_0B_count;
+ }
+ block2[1] =
+ 0x08 | ((program_type_code & 0x18) >> 3);
+ block3[0] = program_identification_code;
+ block3[1] = program_identification_code >> 8;
+ block4[0] = program_service[index1 + 1];
+ block4[1] = program_service[index1 + 0];
+ index1 += 2;
+ group_0B_count++;
+ } else {
+ /* Transmit RT in Group 2A */
+ block1[0] = program_identification_code;
+ block1[1] = program_identification_code >> 8;
+ if (a_b_flag)
+ block2[0] = (0x10 |
+ ((program_type_code & 0x07)
+ << 5)) + group_2A_count;
+ else
+ block2[0] = (0x00 |
+ ((program_type_code & 0x07)
+ << 5)) + group_2A_count;
+ block2[1] = 0x20 | ((program_type_code & 0x18)
+ >> 3);
+ block3[0] = radio_text[index2 + 1];
+ block3[1] = radio_text[index2 + 0];
+ block4[0] = radio_text[index2 + 3];
+ block4[1] = radio_text[index2 + 2];
+ index2 += 4;
+ group_2A_count++;
+ }
+ FM_DEBUG_REPORT("%02x%02x "
+ "%02x%02x "
+ "%02x%02x "
+ "%02x%02x ",
+ block1[1], block1[0],
+ block2[1], block2[0],
+ block3[1], block3[0],
+ block4[1], block4[0]);
+ result = fmd_tx_set_group
+ (context,
+ group_position, block1, block2, block3, block4);
+ group_position++;
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_transmit_rds_groups: "
+ "fmd_tx_set_group failed %d",
+ (unsigned int)result);
+ result = STE_STATUS_SYSTEM_ERROR;
+ break;
+ }
+ }
+ a_b_flag = !a_b_flag;
+ } else {
+ FM_ERR_REPORT("ste_fm_transmit_rds_groups: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
+
+error:
+ FM_DEBUG_REPORT("ste_fm_transmit_rds_groups: returning %s",
+ str_stestatus(result));
+ return result;
}
/**
@@ -451,90 +572,111 @@ static const char *str_stestatus(
* @context: Pointer to the Context of the FM Driver
* @event: event for which the callback function was caled
* from FM Driver.
- * @event_int_data: Data corresponding the event (if any),
- * otherwise it is 0.
- * @event_boolean_data: Signifying whether the event is called from FM Driver
+ * @event_successful: Signifying whether the event is called from FM Driver
* on receiving irpt_OperationSucceeded or irpt_OperationFailed.
*/
-static void ste_fm_driver_callback(
- void *context,
- uint32_t event,
- uint32_t event_int_data,
- bool event_boolean_data
- )
+static void ste_fm_driver_callback(void *context,
+ u8 event, bool event_successful)
{
- FM_DEBUG_REPORT("ste_fm_driver_callback: "\
- "event = %x, event_boolean_data = %x",
- event,
- event_boolean_data);
- switch (event) {
- case FMD_EVENT_GEN_POWERUP:
- FM_DEBUG_REPORT("FMD_EVENT_GEN_POWERUP");
- break;
- case FMD_EVENT_ANTENNA_STATUS_CHANGED:
- FM_DEBUG_REPORT("FMD_EVENT_ANTENNA_STATUS_CHANGED");
- break;
- case FMD_EVENT_FREQUENCY_CHANGED:
- FM_DEBUG_REPORT("FMD_EVENT_FREQUENCY_CHANGED ");
- break;
-
- case FMD_EVENT_FREQUENCY_RANGE_CHANGED:
- FM_DEBUG_REPORT("FMD_EVENT_FREQUENCY_RANGE_CHANGED");
- break;
-
- case FMD_EVENT_ACTION_FINISHED:
- os_set_cmd_sem();
- FM_DEBUG_REPORT("FMD_EVENT_ACTION_FINISHED ");
- break;
-
- case FMD_EVENT_PRESET_CHANGED:
- FM_DEBUG_REPORT("FMD_EVENT_PRESET_CHANGED ");
- break;
-
- case FMD_EVENT_SEEK_STOPPED:
- FM_DEBUG_REPORT("FMD_EVENT_SEEK_STOPPED");
- global_event = STE_EVENT_NO_CHANNELS_FOUND;
- wake_up_poll_queue();
- break;
-
- case FMD_EVENT_SEEK_COMPLETED:
- FM_DEBUG_REPORT("FMD_EVENT_SEEK_COMPLETED");
- global_event = STE_EVENT_SEARCH_CHANNEL_FOUND ;
- wake_up_poll_queue();
- break;
-
- case FMD_EVENT_SCAN_BAND_COMPLETED:
- FM_DEBUG_REPORT("FMD_EVENT_SCAN_BAND_COMPLETED");
- global_event = STE_EVENT_SCAN_CHANNELS_FOUND;
- wake_up_poll_queue();
- break;
-
- case FMD_EVENT_RDSGROUP_RCVD:
- FM_DEBUG_REPORT("FMD_EVENT_RDSGROUP_RCVD");
- os_set_rds_sem();
- break;
-
- default:
- FM_ERR_REPORT("ste_fm_driver_callback: "\
- "Unknown event = %x",
- event);
- break;
+ FM_DEBUG_REPORT("ste_fm_driver_callback: "
+ "event = %02x, event_successful = %x",
+ event, event_successful);
+
+ if (event_successful) {
+ switch (event) {
+ case FMD_EVENT_GEN_POWERUP:
+ FM_DEBUG_REPORT("FMD_EVENT_GEN_POWERUP");
+ break;
+ case FMD_EVENT_ANTENNA_STATUS_CHANGED:
+ FM_DEBUG_REPORT("FMD_EVENT_ANTENNA_STATUS_CHANGED");
+ break;
+ case FMD_EVENT_FREQUENCY_CHANGED:
+ FM_DEBUG_REPORT("FMD_EVENT_FREQUENCY_CHANGED ");
+ break;
+
+ case FMD_EVENT_SEEK_STOPPED:
+ FM_DEBUG_REPORT("FMD_EVENT_SEEK_STOPPED");
+ global_event = STE_EVENT_SCAN_CANCELLED;
+ wake_up_poll_queue();
+ break;
+
+ case FMD_EVENT_SEEK_COMPLETED:
+ FM_DEBUG_REPORT("FMD_EVENT_SEEK_COMPLETED");
+ global_event = STE_EVENT_SEARCH_CHANNEL_FOUND;
+ wake_up_poll_queue();
+ break;
+
+ case FMD_EVENT_SCAN_BAND_COMPLETED:
+ FM_DEBUG_REPORT("FMD_EVENT_SCAN_BAND_COMPLETED");
+ global_event = STE_EVENT_SCAN_CHANNELS_FOUND;
+ wake_up_poll_queue();
+ break;
+
+ case FMD_EVENT_BLOCK_SCAN_COMPLETED:
+ FM_DEBUG_REPORT("FMD_EVENT_BLOCK_SCAN_COMPLETED");
+ global_event = STE_EVENT_BLOCK_SCAN_CHANNELS_FOUND;
+ wake_up_poll_queue();
+ break;
+
+ case FMD_EVENT_AF_UPDATE_SWITCH_COMPLETE:
+ FM_DEBUG_REPORT("FMD_EVENT_AF_UPDATE_SWITCH_COMPLETE");
+ break;
+
+ case FMD_EVENT_RDSGROUP_RCVD:
+ FM_DEBUG_REPORT("FMD_EVENT_RDSGROUP_RCVD");
+ os_set_rds_sem();
+ break;
+
+ default:
+ FM_ERR_REPORT("ste_fm_driver_callback: "
+ "Unknown event = %x", event);
+ break;
+ }
+ } else {
+ switch (event) {
+ /* Seek stop, band scan, seek, block scan could
+ * fail for some reason so wake up poll queue */
+ case FMD_EVENT_SEEK_STOPPED:
+ FM_DEBUG_REPORT("FMD_EVENT_SEEK_STOPPED");
+ global_event = STE_EVENT_SCAN_CANCELLED;
+ wake_up_poll_queue();
+ break;
+ case FMD_EVENT_SEEK_COMPLETED:
+ FM_DEBUG_REPORT("FMD_EVENT_SEEK_COMPLETED");
+ global_event = STE_EVENT_SEARCH_CHANNEL_FOUND;
+ wake_up_poll_queue();
+ break;
+ case FMD_EVENT_SCAN_BAND_COMPLETED:
+ FM_DEBUG_REPORT("FMD_EVENT_SCAN_BAND_COMPLETED");
+ global_event = STE_EVENT_SCAN_CHANNELS_FOUND;
+ wake_up_poll_queue();
+ break;
+ case FMD_EVENT_BLOCK_SCAN_COMPLETED:
+ FM_DEBUG_REPORT("FMD_EVENT_BLOCK_SCAN_COMPLETED");
+ global_event = STE_EVENT_BLOCK_SCAN_CHANNELS_FOUND;
+ wake_up_poll_queue();
+ break;
+ default:
+ FM_ERR_REPORT("ste_fm_driver_callback: "
+ "event = %x failed!!!!", event);
+ break;
+ }
}
}
/**
- * ste_fm_rds_callback()- Function to retrieve the RDS groups from
- * chip on receiving
- * irpt_BufferFull interrupt from Chip.
+ * ste_fm_rds_callback()- Function to retrieve the RDS groups.
+ * This is called when the chip has received enough RDS groups
+ * so an interrupt irpt_BufferFull is generated to read the groups.
*/
static void ste_fm_rds_callback(void)
{
- uint8_t index = 0;
- uint8_t rds_local_buf_count;
+ u8 index = 0;
+ u8 rds_local_buf_count;
FM_DEBUG_REPORT("ste_fm_rds_callback");
if (fm_rds_status) {
/* Wait till interrupt is RDS Buffer
- * Full interrupt is received */
+ * full interrupt is received */
os_get_rds_sem();
}
if (fm_rds_status) {
@@ -546,1630 +688,2237 @@ static void ste_fm_rds_callback(void)
* would be updated */
rds_local_buf_count = 1;
while (index < rds_local_buf_count) {
+ /* Status are in reverse order because of Endianness
+ * of status byte received from chip */
fmd_rx_get_low_level_rds_groups(context,
- index,
- &rds_local_buf_count,
- &ste_fm_rds_buf[head][index].block1,
- &ste_fm_rds_buf[head][index].block2,
- &ste_fm_rds_buf[head][index].block3,
- &ste_fm_rds_buf[head][index].block4,
- &ste_fm_rds_buf[head][index].status2,
- &ste_fm_rds_buf[head][index].status1,
- &ste_fm_rds_buf[head][index].status4,
- &ste_fm_rds_buf[head][index].status3);
- /*FM_DEBUG_REPORT("%04x %04x "\
+ index,
+ &rds_local_buf_count,
+ &ste_fm_rds_buf
+ [ste_fm_rds_info.
+ rds_head]
+ [index].block1,
+ &ste_fm_rds_buf
+ [ste_fm_rds_info.
+ rds_head]
+ [index].block2,
+ &ste_fm_rds_buf
+ [ste_fm_rds_info.
+ rds_head]
+ [index].block3,
+ &ste_fm_rds_buf
+ [ste_fm_rds_info.
+ rds_head]
+ [index].block4,
+ &ste_fm_rds_buf
+ [ste_fm_rds_info.
+ rds_head]
+ [index].status2,
+ &ste_fm_rds_buf
+ [ste_fm_rds_info.
+ rds_head]
+ [index].status1,
+ &ste_fm_rds_buf
+ [ste_fm_rds_info.
+ rds_head]
+ [index].status4,
+ &ste_fm_rds_buf
+ [ste_fm_rds_info.
+ rds_head]
+ [index].status3);
+ /*FM_DEBUG_REPORT("%04x %04x "\
"%04x %04x %02x %02x "\
- "%02x %02x", ste_fm_rds_buf[head][index].block1,
- ste_fm_rds_buf[head][index].block2,
- ste_fm_rds_buf[head][index].block3,
- ste_fm_rds_buf[head][index].block4,
- ste_fm_rds_buf[head][index].status1,
- ste_fm_rds_buf[head][index].status2,
- ste_fm_rds_buf[head][index].status3,
- ste_fm_rds_buf[head][index].status4);*/
+ "%02x %02x", ste_fm_rds_buf[ste_fm_rds_info.rds_head]
+ [index].block1,
+ ste_fm_rds_buf[ste_fm_rds_info.rds_head][index].block2,
+ ste_fm_rds_buf[ste_fm_rds_info.rds_head][index].block3,
+ ste_fm_rds_buf[ste_fm_rds_info.rds_head][index].block4,
+ ste_fm_rds_buf[ste_fm_rds_info.rds_head][index].status1,
+ ste_fm_rds_buf[ste_fm_rds_info.rds_head][index].status2,
+ ste_fm_rds_buf[ste_fm_rds_info.rds_head][index].status3,
+ ste_fm_rds_buf[ste_fm_rds_info.rds_head]
+ [index].status4); */
index++;
}
- head++;
- if (head == MAX_RDS_BUFFER)
- head = 0;
+ ste_fm_rds_info.rds_head++;
+ if (ste_fm_rds_info.rds_head == MAX_RDS_BUFFER)
+ ste_fm_rds_info.rds_head = 0;
+ wake_up_read_queue();
mutex_unlock(&rds_mutex);
}
}
+/**
+ * str_stestatus()- Returns the status value as a printable string.
+ * @status: Status
+ *
+ * Returns:
+ * Pointer to a string containing printable value of status
+ */
+static const char *str_stestatus(u8 status)
+{
+ switch (status) {
+ case STE_STATUS_OK:
+ return "STE_STATUS_OK";
+ case STE_STATUS_SYSTEM_ERROR:
+ return "STE_STATUS_SYSTEM_ERROR";
+ default:
+ return "Unknown status";
+ }
+}
+
/* ------------------ External function definitions ---------------------- */
-uint8_t ste_fm_init(void)
+u8 ste_fm_init(void)
{
- uint8_t result = STE_STATUS_OK;
+ u8 result = STE_STATUS_OK;
FM_INFO_REPORT("ste_fm_init");
- if (STE_FALSE == fm_init) {
+ if (STE_FM_STATE_DEINITIALIZED == ste_fm_state) {
mutex_init(&rds_mutex);
/* Initalize the Driver */
- if (fmd_init(&context) != FMD_RESULT_SUCCESS)
- return STE_STATUS_SYSTEM_ERROR;
+ if (fmd_init(&context) != FMD_RESULT_SUCCESS) {
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
/* Register the callback */
if (fmd_register_callback(context,
- (fmd_radio_cb)ste_fm_driver_callback)
- != FMD_RESULT_SUCCESS)
- return STE_STATUS_SYSTEM_ERROR;
+ (fmd_radio_cb) ste_fm_driver_callback)
+ != FMD_RESULT_SUCCESS) {
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
/* initialize global variables */
global_event = STE_EVENT_NO_EVENT;
- if (STE_STATUS_OK == result) {
- fm_init = STE_TRUE;
- fm_power_on = STE_FALSE;
- fm_stand_by = STE_FALSE;
- }
+ ste_fm_state = STE_FM_STATE_INITIALIZED;
+ ste_fm_mode = STE_FM_IDLE_MODE;
+ memset(&ste_fm_rds_info, 0, sizeof(struct ste_fm_rds_info_t));
+ memset(ste_fm_rds_buf, 0,
+ sizeof(struct ste_fm_rds_buf_t) *
+ MAX_RDS_BUFFER * MAX_RDS_GROUPS);
} else {
FM_ERR_REPORT("ste_fm_init: Already Initialized");
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
+error:
FM_DEBUG_REPORT("ste_fm_init: returning %s", str_stestatus(result));
return result;
}
-uint8_t ste_fm_deinit(void)
+u8 ste_fm_deinit(void)
{
- uint8_t result = STE_STATUS_OK;
+ u8 result = STE_STATUS_OK;
FM_INFO_REPORT("ste_fm_deinit");
- if (STE_TRUE == fm_init) {
- if (STE_STATUS_OK == result) {
- os_fm_driver_deinit();
- context = NULL;
- fm_power_on = STE_FALSE;
- fm_stand_by = STE_FALSE;
- fm_init = STE_FALSE;
- }
+ if (STE_FM_STATE_INITIALIZED == ste_fm_state) {
+ fmd_deinit();
+ mutex_destroy(&rds_mutex);
+ context = NULL;
+ ste_fm_state = STE_FM_STATE_DEINITIALIZED;
+ ste_fm_mode = STE_FM_IDLE_MODE;
} else {
- FM_ERR_REPORT("ste_fm_deinit: Already De-initialized");
+ FM_ERR_REPORT("ste_fm_deinit: Already de-Initialized");
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
+error:
FM_DEBUG_REPORT("ste_fm_deinit: returning %s", str_stestatus(result));
return result;
}
-uint8_t ste_fm_switch_on(
- struct device *device,
- uint32_t freq,
- uint8_t band,
- uint8_t grid
- )
+u8 ste_fm_switch_on(struct device *device)
{
- uint8_t result = STE_STATUS_OK;
+ u8 result = STE_STATUS_OK;
- FM_INFO_REPORT("ste_fm_switch_on: freq = %d Hz, "\
- "band = %d, grid = %d", freq, band, grid);
+ FM_INFO_REPORT("ste_fm_switch_on");
- if (STE_TRUE == fm_init) {
- if (STE_FALSE == fm_power_on) {
+ if (STE_FM_STATE_INITIALIZED == ste_fm_state) {
+ /* Enable FM IP */
+ FM_DEBUG_REPORT("ste_fm_switch_on: " "Sending FM IP Enable");
- /* Enable FM IP */
- FM_DEBUG_REPORT("ste_fm_switch_on: "\
- "Sending FM IP Enable");
+ if (fmd_send_fm_ip_enable()) {
+ FM_ERR_REPORT("ste_fm_switch_on: "
+ "Error in fmd_send_fm_ip_enable");
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
- if (fmd_send_fm_ip_enable()) {
- FM_ERR_REPORT("ste_fm_switch_on: "\
- "Error in fmd_send_fm_ip_enable");
- result = STE_STATUS_SYSTEM_ERROR;
- goto error;
- }
+ /* Now Download the Coefficient Files and FM Firmware */
+ if (STE_STATUS_OK != ste_fm_load_firmware(device)) {
+ FM_ERR_REPORT("ste_fm_switch_on: "
+ "Error in downloading firmware");
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
- /* Now Download the Coefficient Files and FM Firmware */
- if (STE_STATUS_OK != ste_fm_load_firmware(device)) {
- FM_ERR_REPORT("ste_fm_switch_on: "\
- "Error in downloading firmware");
- result = STE_STATUS_SYSTEM_ERROR;
+ /* Power up FM */
+ result = fmd_power_up(context);
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_switch_on: "
+ "fmd_power_up failed %x",
+ (unsigned int)result);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
+
+ /* Enable the Ref Clk */
+ FM_DEBUG_REPORT("ste_fm_switch_on: "
+ "Sending fmd_select_ref_clk");
+ result = fmd_select_ref_clk(context, 0x0001);
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_switch_on: "
+ "fmd_select_ref_clk failed %x",
+ (unsigned int)result);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
+
+ /* Select the Frequency of Ref Clk (28 MHz) */
+ FM_DEBUG_REPORT("ste_fm_switch_on: "
+ "Sending fmd_set_ref_clk_pll");
+ result = fmd_set_ref_clk_pll(context, 0x32C8);
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_switch_on: "
+ "fmd_select_ref_clk_pll failed %x",
+ (unsigned int)result);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
+ } else {
+ FM_ERR_REPORT("ste_fm_switch_on: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
+ ste_fm_state = STE_FM_STATE_SWITCHED_ON;
+ ste_fm_mode = STE_FM_IDLE_MODE;
+ memset(&ste_fm_rds_info, 0, sizeof(struct ste_fm_rds_info_t));
+ memset(ste_fm_rds_buf, 0,
+ sizeof(struct ste_fm_rds_buf_t) *
+ MAX_RDS_BUFFER * MAX_RDS_GROUPS);
+
+error:
+ FM_DEBUG_REPORT("ste_fm_switch_on: returning %s",
+ str_stestatus(result));
+ return result;
+}
+
+u8 ste_fm_switch_off(void)
+{
+ u8 result = STE_STATUS_OK;
+
+ FM_INFO_REPORT("ste_fm_switch_off");
+
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+ /* Stop the RDS Thread if it is running */
+ if (fm_rds_status) {
+ fm_rds_status = STE_FALSE;
+ os_stop_rds_thread();
+ }
+ result = fmd_goto_power_down(context);
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_switch_off: "
+ "FMLGotoPowerdown failed = %d",
+ (unsigned int)result);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
+ if (STE_STATUS_OK == result) {
+ if (fmd_send_fm_ip_disable()) {
+ FM_ERR_REPORT("ste_fm_switch_off: "
+ "Problem in fmd_send_fm_ip_"
+ "disable");
+ result = STE_STATUS_SYSTEM_ERROR;
goto error;
}
+ }
+ if (STE_STATUS_OK == result) {
+ ste_fm_state = STE_FM_STATE_INITIALIZED;
+ ste_fm_mode = STE_FM_IDLE_MODE;
+ memset(&ste_fm_rds_info, 0,
+ sizeof(struct ste_fm_rds_info_t));
+ memset(ste_fm_rds_buf, 0,
+ sizeof(struct ste_fm_rds_buf_t) *
+ MAX_RDS_BUFFER * MAX_RDS_GROUPS);
+ }
+ } else {
+ FM_ERR_REPORT("ste_fm_switch_off: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
- if (STE_STATUS_OK == result) {
- /* Power up FM */
- result = fmd_power_up(context);
- if (FMD_RESULT_WAIT != result) {
- FM_ERR_REPORT("ste_fm_switch_on: "\
- "fmd_power_up failed %x",
- (unsigned int)result);
- result = STE_STATUS_SYSTEM_ERROR;
- goto error;
- } else {
- /* Wait till cmd is complete */
- os_get_cmd_sem();
- result = STE_STATUS_OK;
- }
- }
+error:
+ FM_DEBUG_REPORT("ste_fm_switch_off: returning %s",
+ str_stestatus(result));
+ return result;
+}
- if (STE_STATUS_OK == result) {
- /* Switch To Rx mode */
- FM_DEBUG_REPORT("ste_fm_switch_on: "\
- "fmd_power_up interrupt received, "\
- "Sending Set mode to Rx");
- result = fmd_set_mode(context, FMD_MODE_RX);
- if (FMD_RESULT_WAIT != result) {
- FM_ERR_REPORT("ste_fm_switch_on: "\
- "fmd_set_mode failed %x", \
- (unsigned int)result);
- result = STE_STATUS_SYSTEM_ERROR;
- goto error;
- } else {
- /* Wait till cmd is complete */
- os_get_cmd_sem();
- result = STE_STATUS_OK;
- }
- }
+u8 ste_fm_standby(void)
+{
+ u8 result = STE_STATUS_OK;
- if (STE_STATUS_OK == result) {
- /* Power Up Audio DAC */
- FM_DEBUG_REPORT("ste_fm_switch_on: "\
- "Set mode To Rx interrupt "\
- "received, Sending Set "\
- "fmd_set_audio_dac");
- result = fmd_set_audio_dac
- (context, STE_FM_DAC_ON);
- if (FMD_RESULT_SUCCESS != result) {
- FM_ERR_REPORT("ste_fm_switch_on: "\
- "FMRSetAudioDAC failed %x", \
- (unsigned int)result);
- result = STE_STATUS_SYSTEM_ERROR;
- goto error;
- } else
- result = STE_STATUS_OK;
- }
+ FM_INFO_REPORT("ste_fm_standby");
- if (STE_STATUS_OK == result) {
- /* Enable the Ref Clk */
- FM_DEBUG_REPORT("ste_fm_switch_on: "\
- "Sending Set fmd_select_ref_clk");
- result = fmd_select_ref_clk(context, 0x0001);
- if (FMD_RESULT_SUCCESS != result) {
- FM_ERR_REPORT("ste_fm_switch_on: "\
- "fmd_select_ref_clk failed %x", \
- (unsigned int)result);
- result = STE_STATUS_SYSTEM_ERROR;
- goto error;
- } else
- result = STE_STATUS_OK;
- }
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+ result = fmd_goto_standby(context);
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_standby: "
+ "FMLGotoStandby failed, "
+ "err = %d", (unsigned int)result);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
+ ste_fm_state = STE_FM_STATE_STAND_BY;
+ } else {
+ FM_ERR_REPORT("ste_fm_standby: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
- if (STE_STATUS_OK == result) {
- /* Select the Frequency of Ref Clk (28 MHz)*/
- FM_DEBUG_REPORT("ste_fm_switch_on: "\
- "Sending Set fmd_select_ref_clk_pll");
- result = fmd_select_ref_clk_pll
- (context, 0x32C8);
- if (FMD_RESULT_SUCCESS != result) {
- FM_ERR_REPORT("ste_fm_switch_on: "\
- "fmd_select_ref_clk_pll failed %x", \
- (unsigned int)result);
- result = STE_STATUS_SYSTEM_ERROR;
- goto error;
- } else
- result = STE_STATUS_OK;
- }
+error:
+ FM_DEBUG_REPORT("ste_fm_standby: returning %s", str_stestatus(result));
+ return result;
+}
- if (STE_STATUS_OK == result) {
- /* Set the Grid */
- result = fmd_rx_set_grid(context, grid);
- if (FMD_RESULT_SUCCESS != result) {
- FM_ERR_REPORT("ste_fm_switch_on: "\
- "fmd_rx_set_grid failed %x", \
- (unsigned int)result);
- result = STE_STATUS_SYSTEM_ERROR;
- goto error;
- } else
- result = STE_STATUS_OK;
- }
+u8 ste_fm_power_up_from_standby(void)
+{
+ u8 result = STE_STATUS_OK;
- if (STE_STATUS_OK == result) {
- switch (band) {
- case STE_FM_BAND_US_EU:
- default:
- gfreq_range =
- FMD_FREQRANGE_FMEUROAMERICA;
- break;
- case STE_FM_BAND_JAPAN:
- gfreq_range = FMD_FREQRANGE_FMJAPAN;
- break;
- case STE_FM_BAND_CHINA:
- gfreq_range = FMD_FREQRANGE_FMCHINA;
- break;
- }
- }
+ FM_INFO_REPORT("ste_fm_power_up_from_standby");
- if (STE_STATUS_OK == result) {
- /* Set the Band */
- FM_DEBUG_REPORT("ste_fm_switch_on: "\
- "Sending Set fmd_set_freq_range");
- result = fmd_set_freq_range(context,
- gfreq_range);
+ if (STE_FM_STATE_STAND_BY == ste_fm_state) {
+ /* Power up FM */
+ result = fmd_power_up(context);
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_power_up_from_standby: "
+ "fmd_power_up failed %x",
+ (unsigned int)result);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ } else {
+ ste_fm_state = STE_FM_STATE_SWITCHED_ON;
+ if (STE_FM_TX_MODE == ste_fm_mode) {
+ /* Enable the PA */
+ result = fmd_tx_set_pa(context, STE_TRUE);
if (FMD_RESULT_SUCCESS != result) {
- FM_ERR_REPORT("ste_fm_switch_on: "\
- "fmd_rx_set_grid failed %x",
- (unsigned int)result);
- result = STE_STATUS_SYSTEM_ERROR;
- goto error;
- } else
- result = STE_STATUS_OK;
- }
-
- if (STE_STATUS_OK == result) {
- /* Set the Frequency */
- FM_DEBUG_REPORT("ste_fm_switch_on: "\
- "Sending Set fmd_rx_set_frequency");
- result = fmd_rx_set_frequency(context,
- freq/1000);
- if (FMD_RESULT_WAIT != result) {
- FM_ERR_REPORT("ste_fm_switch_on: "\
- "fmd_rx_set_frequency failed %x",
- (unsigned int)result);
+ FM_ERR_REPORT
+ ("ste_fm_power_up_from_standby:"
+ " fmd_tx_set_pa " "failed %d",
+ (unsigned int)result);
result = STE_STATUS_SYSTEM_ERROR;
goto error;
- } else {
- /* Wait till cmd is complete */
- os_get_cmd_sem();
- result = STE_STATUS_OK;
}
}
+ }
+ } else {
+ FM_ERR_REPORT("ste_fm_power_up_from_standby: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
- if (STE_STATUS_OK == result) {
- FM_DEBUG_REPORT("ste_fm_switch_on: "\
- "SetFrequency interrupt received, "\
- "Sending Set fmd_rx_set_stereo_mode");
+error:
+ FM_DEBUG_REPORT("ste_fm_power_up_from_standby: returning %s",
+ str_stestatus(result));
+ return result;
+}
- /* Set the Stereo mode */
- result = fmd_rx_set_stereo_mode
- (context, FMD_STEREOMODE_STEREO);
- if (FMD_RESULT_SUCCESS != result) {
- FM_ERR_REPORT("ste_fm_switch_on: "\
- "fmd_rx_set_stereo_mode "\
- "failed %d",
- (unsigned int)result);
- result = STE_STATUS_SYSTEM_ERROR;
- goto error;
- } else
- result = STE_STATUS_OK;
- }
+u8 ste_fm_set_rx_default_settings(u32 freq,
+ u8 band,
+ u8 grid, bool enable_rds, bool enable_stereo)
+{
+ u8 result = STE_STATUS_OK;
+ u8 vol_in_percentage;
+
+ FM_INFO_REPORT("ste_fm_set_rx_default_settings: freq = %d Hz, "
+ "band = %d, grid = %d, RDS = %d, Stereo Mode = %d",
+ freq, band, grid, enable_rds, enable_stereo);
+
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+ ste_fm_mode = STE_FM_RX_MODE;
+
+ FM_DEBUG_REPORT("ste_fm_set_rx_default_settings: "
+ "Sending Set mode to Rx");
+ result = fmd_set_mode(context, FMD_MODE_RX);
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_set_rx_default_settings: "
+ "fmd_set_mode failed %x",
+ (unsigned int)result);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
- if (STE_STATUS_OK == result) {
- /* Set the Up Sampling for Ext Audio Control */
- FM_DEBUG_REPORT("ste_fm_switch_on: "\
- "Sending Set fmd_ext_set_ctrl");
- result = fmd_ext_set_ctrl(context, STE_TRUE);
- if (FMD_RESULT_SUCCESS != result) {
- FM_ERR_REPORT("ste_fm_switch_on: "\
- "fmd_ext_set_ctrl "\
- "failed %x",
- (unsigned int)result);
- result = STE_STATUS_SYSTEM_ERROR;
- goto error;
- } else
- result = STE_STATUS_OK;
- }
+ /* Set the Grid */
+ FM_DEBUG_REPORT("ste_fm_set_rx_default_settings: "
+ "Sending fmd_rx_set_grid ");
+ result = fmd_rx_set_grid(context, grid);
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_set_rx_default_settings: "
+ "fmd_rx_set_grid failed %x",
+ (unsigned int)result);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
- if (STE_STATUS_OK == result) {
- /* Set the Digital Audio Ext Control */
- FM_DEBUG_REPORT("ste_fm_switch_on: "\
- "Sending Set fmd_ext_set_mode");
- result = fmd_ext_set_mode
- (context, FMD_OUTPUT_PARALLEL);
- if (FMD_RESULT_SUCCESS != result) {
- FM_ERR_REPORT("ste_fm_switch_on: "\
- "fmd_ext_set_mode "\
- "failed %x",
- (unsigned int)result);
- result = STE_STATUS_SYSTEM_ERROR;
- goto error;
- } else
- result = STE_STATUS_OK;
- }
+ /* Set the Band */
+ FM_DEBUG_REPORT("ste_fm_set_rx_default_settings: "
+ "Sending Set fmd_set_freq_range");
+ result = fmd_set_freq_range(context, band);
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_set_rx_default_settings: "
+ "fmd_rx_set_grid failed %x",
+ (unsigned int)result);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
- if (STE_STATUS_OK == result) {
- /* Set the Analog Out Volume to Max */
- uint8_t vol_in_percentage;
- fm_power_on = STE_TRUE;
- fm_stand_by = STE_FALSE;
- vol_index = 20;
- vol_in_percentage = (uint8_t) \
- (((uint16_t)(vol_index) * 100)/20);
- result = fmd_set_volume
- (context, vol_in_percentage);
- if (FMD_RESULT_SUCCESS != result) {
- FM_ERR_REPORT("ste_fm_switch_on: "\
- "FMRSetVolume failed %x", \
- (unsigned int)result);
- result = STE_STATUS_SYSTEM_ERROR;
- goto error;
- } else
- result = STE_STATUS_OK;
- }
+ /* Set the Frequency */
+ FM_DEBUG_REPORT("ste_fm_set_rx_default_settings: "
+ "Sending Set fmd_rx_set_frequency");
+ result = fmd_rx_set_frequency(context, freq / 1000);
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_set_rx_default_settings: "
+ "fmd_rx_set_frequency failed %x",
+ (unsigned int)result);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
+
+ FM_DEBUG_REPORT("ste_fm_set_rx_default_settings: "
+ "SetFrequency interrupt received, "
+ "Sending Set fmd_rx_set_stereo_mode");
+
+ if (STE_TRUE == enable_stereo) {
+ /* Set the Stereo Blending mode */
+ result = fmd_rx_set_stereo_mode
+ (context, FMD_STEREOMODE_BLENDING);
+ } else {
+ /* Set the Mono mode */
+ result = fmd_rx_set_stereo_mode
+ (context, FMD_STEREOMODE_MONO);
+ }
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_set_rx_default_settings: "
+ "fmd_rx_set_stereo_mode "
+ "failed %d", (unsigned int)result);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
+
+ FM_DEBUG_REPORT("ste_fm_set_rx_default_settings: "
+ "Sending Set rds");
+
+ if (STE_TRUE == enable_rds) {
+ /* Enable RDS */
+ result = ste_fm_rds_on();
} else {
- FM_ERR_REPORT("ste_fm_switch_on: Already Switched on");
+ /* Disable RDS */
+ result = ste_fm_rds_off();
+ }
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_set_rx_default_settings: "
+ "ste_fm_rds_on "
+ "failed %d", (unsigned int)result);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
+
+ /* Set the Analog Out Volume to Max */
+ vol_in_percentage = (u8)
+ (((u16) (MAX_ANALOG_VOLUME) * 100)
+ / MAX_ANALOG_VOLUME);
+ result = fmd_set_volume(context, vol_in_percentage);
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_switch_on: "
+ "FMRSetVolume failed %x",
+ (unsigned int)result);
result = STE_STATUS_SYSTEM_ERROR;
goto error;
}
} else {
- FM_ERR_REPORT("ste_fm_switch_on: FM not initialized");
+ FM_ERR_REPORT("ste_fm_set_rx_default_settings: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
result = STE_STATUS_SYSTEM_ERROR;
goto error;
}
error:
- FM_DEBUG_REPORT("ste_fm_switch_on: returning %s",
+ FM_DEBUG_REPORT("ste_fm_set_rx_default_settings: returning %s",
str_stestatus(result));
return result;
}
-uint8_t ste_fm_switch_off(void)
+u8 ste_fm_set_tx_default_settings(u32 freq,
+ u8 band,
+ u8 grid, bool enable_rds, bool enable_stereo)
{
- uint8_t result = STE_STATUS_OK;
+ u8 result = STE_STATUS_OK;
+
+ FM_INFO_REPORT("ste_fm_set_tx_default_settings: freq = %d Hz, "
+ "band = %d, grid = %d, RDS = %d, Stereo Mode = %d",
+ freq, band, grid, enable_rds, enable_stereo);
+
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+ ste_fm_mode = STE_FM_TX_MODE;
+ if (fm_rds_status) {
+ fm_rds_status = STE_FALSE;
+ os_stop_rds_thread();
+ memset(&ste_fm_rds_info, 0,
+ sizeof(struct ste_fm_rds_info_t));
+ memset(ste_fm_rds_buf, 0,
+ sizeof(struct ste_fm_rds_buf_t) *
+ MAX_RDS_BUFFER * MAX_RDS_GROUPS);
+ os_sleep(50);
+ }
- FM_INFO_REPORT("ste_fm_switch_off");
+ /* Switch To Tx mode */
+ FM_DEBUG_REPORT("ste_fm_set_tx_default_settings: "
+ "Sending Set mode to Tx");
+ result = fmd_set_mode(context, FMD_MODE_TX);
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_set_tx_default_settings: "
+ "fmd_set_mode failed %x",
+ (unsigned int)result);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
- if (STE_TRUE == fm_init) {
- if (STE_TRUE == fm_power_on) {
- /* Stop the RDS Thread if it is running */
- if (fm_rds_status) {
- fm_rds_status = STE_FALSE;
- os_stop_rds_thread();
- }
- result = fmd_goto_power_down
- (context);
- if (FMD_RESULT_SUCCESS != result) {
- FM_ERR_REPORT("ste_fm_switch_off: "\
- "FMLGotoPowerdown failed = %d",
- (unsigned int)result);
- result = STE_STATUS_SYSTEM_ERROR;
- }
- if (STE_STATUS_OK == result) {
- if (fmd_send_fm_ip_disable()) {
- FM_ERR_REPORT("ste_fm_switch_off: "\
- "Problem in fmd_send_fm_ip_disable");
- result = STE_STATUS_SYSTEM_ERROR;
- }
- }
- if (STE_STATUS_OK == result) {
- fm_power_on = STE_FALSE;
- fm_stand_by = STE_FALSE;
- head = 0;
- tail = 0;
- rds_group_sent = 0;
- rds_block_sent = 0;
- memset(ste_fm_rds_buf, 0,
- sizeof(struct ste_fm_rds_buf_s) *
- MAX_RDS_BUFFER *
- MAX_RDS_GROUPS_READ);
- }
+ /* Set the Grid */
+ FM_DEBUG_REPORT("ste_fm_set_tx_default_settings: "
+ "Sending fmd_tx_set_grid ");
+ result = fmd_tx_set_grid(context, grid);
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_set_tx_default_settings: "
+ "fmd_tx_set_grid failed %x",
+ (unsigned int)result);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
- } else {
- FM_ERR_REPORT("ste_fm_switch_off: "\
- "Already Switched Off");
+ /* Set the Band */
+ FM_DEBUG_REPORT("ste_fm_set_tx_default_settings: "
+ "Sending fmd_tx_set_freq_range");
+ result = fmd_tx_set_freq_range(context, band);
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_set_tx_default_settings: "
+ "fmd_tx_set_freq_range failed %x",
+ (unsigned int)result);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
+
+ /* Set the Band */
+ FM_DEBUG_REPORT("ste_fm_set_tx_default_settings: "
+ "Sending fmd_tx_set_preemphasis");
+ result = fmd_tx_set_preemphasis(context, FMD_EMPHASIS_75US);
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_switch_on: "
+ "fmd_tx_set_preemphasis failed %x",
+ (unsigned int)result);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
+
+ /* Set the Frequency */
+ FM_DEBUG_REPORT("ste_fm_set_tx_default_settings: "
+ "Sending Set fmd_tx_set_frequency");
+ result = fmd_tx_set_frequency(context, (freq / 1000));
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_switch_on: "
+ "fmd_tx_set_frequency failed %x",
+ (unsigned int)result);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
+
+ FM_DEBUG_REPORT("ste_fm_set_tx_default_settings: "
+ "SetFrequency interrupt received, "
+ "Sending Set fmd_tx_enable_stereo_mode");
+
+ /* Set the Stereo mode */
+ result = fmd_tx_enable_stereo_mode(context, enable_stereo);
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_set_tx_default_settings: "
+ "fmd_tx_enable_stereo_mode "
+ "failed %d", (unsigned int)result);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
+
+ FM_DEBUG_REPORT("ste_fm_set_tx_default_settings: "
+ "Sending Set fmd_tx_set_pa");
+
+ /* Enable the PA */
+ result = fmd_tx_set_pa(context, STE_TRUE);
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_set_tx_default_settings: "
+ "fmd_tx_set_pa "
+ "failed %d", (unsigned int)result);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
+
+ FM_DEBUG_REPORT("ste_fm_set_tx_default_settings: "
+ "set PA interrupt received, "
+ "Sending Set fmd_tx_set_signal_strength");
+
+ /* Set the Signal Strength to Max */
+ result = fmd_tx_set_signal_strength(context, 123);
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_set_tx_default_settings: "
+ "fmd_tx_set_signal_strength "
+ "failed %d", (unsigned int)result);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
+
+ /* Enable Tx RDS */
+ FM_DEBUG_REPORT("ste_fm_set_tx_default_settings: "
+ "Sending Set ste_fm_tx_rds");
+ result = ste_fm_tx_rds(enable_rds);
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_set_tx_default_settings: "
+ "ste_fm_tx_rds "
+ "failed %x", (unsigned int)result);
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
} else {
- FM_ERR_REPORT("ste_fm_switch_off: FM not initialized");
+ FM_ERR_REPORT("ste_fm_set_tx_default_settings: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
- FM_DEBUG_REPORT("ste_fm_switch_off: returning %s",
+error:
+ FM_DEBUG_REPORT("ste_fm_set_tx_default_settings: returning %s",
str_stestatus(result));
return result;
}
-uint8_t ste_fm_standby(void)
+u8 ste_fm_set_grid(u8 grid)
{
- uint8_t result = STE_STATUS_OK;
+ u8 result = STE_STATUS_OK;
- FM_INFO_REPORT("ste_fm_standby");
+ FM_INFO_REPORT("ste_fm_set_grid: Grid = %d", grid);
- if (STE_TRUE == fm_init) {
- if (STE_TRUE == fm_power_on && STE_FALSE == fm_stand_by) {
- result = fmd_goto_standby(context);
- if (FMD_RESULT_SUCCESS != result) {
- FM_ERR_REPORT("ste_fm_standby: "\
- "FMLGotoStandby failed, "\
- "err = %d", (unsigned int)result);
- result = STE_STATUS_SYSTEM_ERROR;
- }
- fm_stand_by = STE_TRUE;
- } else {
- FM_ERR_REPORT("ste_fm_standby: FM not switched on");
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+ result = fmd_rx_set_grid(context, grid);
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_set_grid: "
+ "fmd_rx_set_grid failed");
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
} else {
- FM_ERR_REPORT("ste_fm_standby: FM not initialized");
+ FM_ERR_REPORT("ste_fm_set_grid: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
- FM_DEBUG_REPORT("ste_fm_standby: returning %s", str_stestatus(result));
+error:
+ FM_DEBUG_REPORT("ste_fm_set_grid: returning %s", str_stestatus(result));
return result;
}
-uint8_t ste_fm_power_up_from_standby(void)
+u8 ste_fm_set_band(u8 band)
{
- uint8_t result = STE_STATUS_OK;
+ u8 result = STE_STATUS_OK;
- FM_INFO_REPORT("ste_fm_power_up_from_standby");
+ FM_INFO_REPORT("ste_fm_set_band: Band = %d", band);
- if (STE_TRUE == fm_init) {
- if (STE_TRUE == fm_power_on && STE_TRUE == fm_stand_by) {
- /* Power up FM */
- result = fmd_power_up(context);
- if (FMD_RESULT_WAIT != result) {
- FM_ERR_REPORT("ste_fm_power_up_from_standby: "\
- "fmd_power_up failed %x", (unsigned int)result);
- result = STE_STATUS_SYSTEM_ERROR;
- goto error;
- } else {
- /* Wait till cmd is complete */
- os_get_cmd_sem();
- result = STE_STATUS_OK;
- }
- fm_stand_by = STE_FALSE;
- } else {
- FM_ERR_REPORT("ste_fm_power_up_from_standby: "\
- "FM not switched on");
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+ result = fmd_set_freq_range(context, band);
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_set_band: "
+ "fmd_set_freq_range failed %d",
+ (unsigned int)result);
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
} else {
- FM_ERR_REPORT("ste_fm_power_up_from_standby: "\
- "FM not initialized");
+ FM_ERR_REPORT("ste_fm_set_band: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
error:
- FM_DEBUG_REPORT("ste_fm_power_up_from_standby: returning %s",
- str_stestatus(result));
+ FM_DEBUG_REPORT("ste_fm_set_band: returning %s", str_stestatus(result));
return result;
}
-uint8_t ste_fm_set_grid(
- uint8_t grid
- )
+u8 ste_fm_search_up_freq(void)
{
- uint8_t result = STE_STATUS_OK;
+ u8 result = STE_STATUS_OK;
- FM_INFO_REPORT("ste_fm_set_grid: Grid = %d", grid);
+ FM_INFO_REPORT("ste_fm_search_up_freq");
- if (STE_TRUE == fm_init) {
- if (STE_TRUE == fm_power_on && STE_FALSE == fm_stand_by) {
- result = fmd_rx_set_grid(context, grid);
- if (FMD_RESULT_SUCCESS != result) {
- FM_ERR_REPORT("ste_fm_set_grid: "\
- "fmd_rx_set_grid failed");
- result = STE_STATUS_SYSTEM_ERROR;
- }
- } else {
- FM_ERR_REPORT("ste_fm_set_grid: FM not switched on");
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+ if (fm_rds_status) {
+ /* Stop RDS if it is active */
+ result = ste_fm_rds_off();
+ fm_prev_rds_status = STE_TRUE;
+ }
+ result = fmd_rx_seek(context, STE_DIR_UP);
+ if (FMD_RESULT_ONGOING != result) {
+ FM_ERR_REPORT("ste_fm_search_up_freq: "
+ "Error Code %d", (unsigned int)result);
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ } else {
+ memset(&ste_fm_rds_info, 0,
+ sizeof(struct ste_fm_rds_info_t));
+ memset(ste_fm_rds_buf, 0,
+ sizeof(struct ste_fm_rds_buf_t) *
+ MAX_RDS_BUFFER * MAX_RDS_GROUPS);
+ result = STE_STATUS_OK;
}
} else {
- FM_ERR_REPORT("ste_fm_set_grid: FM not initialized");
+ FM_ERR_REPORT("ste_fm_search_up_freq: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
- FM_DEBUG_REPORT("ste_fm_set_grid: returning %s", str_stestatus(result));
+error:
+ FM_DEBUG_REPORT("ste_fm_search_up_freq: returning %s",
+ str_stestatus(result));
return result;
}
-uint8_t ste_fm_set_band(
- uint8_t band
- )
+u8 ste_fm_search_down_freq(void)
{
- uint8_t result = STE_STATUS_OK;
- uint8_t FreqRange = FMD_FREQRANGE_FMEUROAMERICA;
+ u8 result = STE_STATUS_OK;
- FM_INFO_REPORT("ste_fm_set_band: Band = %d", band);
+ FM_INFO_REPORT("ste_fm_search_down_freq");
- if (STE_TRUE == fm_init) {
- if (STE_TRUE == fm_power_on && STE_FALSE == fm_stand_by) {
- switch (band) {
- case STE_FM_BAND_US_EU:
- default:
- FreqRange = FMD_FREQRANGE_FMEUROAMERICA;
- break;
- case STE_FM_BAND_JAPAN:
- FreqRange = FMD_FREQRANGE_FMJAPAN;
- break;
- case STE_FM_BAND_CHINA:
- FreqRange = FMD_FREQRANGE_FMCHINA;
- break;
- }
- result = fmd_set_freq_range(context, FreqRange);
- if (FMD_RESULT_SUCCESS != result) {
- FM_ERR_REPORT("ste_fm_set_band: "\
- "fmd_set_freq_range failed %d", \
- (unsigned int)result);
- result = STE_STATUS_SYSTEM_ERROR;
- }
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+ if (fm_rds_status) {
+ /* Stop RDS if it is active */
+ result = ste_fm_rds_off();
+ fm_prev_rds_status = STE_TRUE;
+ }
+ result = fmd_rx_seek(context, STE_DIR_DOWN);
+ if (FMD_RESULT_ONGOING != result) {
+ FM_ERR_REPORT("ste_fm_search_down_freq: "
+ "Error Code %d", (unsigned int)result);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
} else {
- FM_ERR_REPORT("ste_fm_set_band: FM not switched on");
+ memset(&ste_fm_rds_info, 0,
+ sizeof(struct ste_fm_rds_info_t));
+ memset(ste_fm_rds_buf, 0,
+ sizeof(struct ste_fm_rds_buf_t) *
+ MAX_RDS_BUFFER * MAX_RDS_GROUPS);
+ result = STE_STATUS_OK;
+ }
+ } else {
+ FM_ERR_REPORT("ste_fm_search_down_freq: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
+
+error:
+ FM_DEBUG_REPORT("ste_fm_search_down_freq: returning %s",
+ str_stestatus(result));
+ return result;
+}
+
+u8 ste_fm_start_band_scan(void)
+{
+ u8 result = STE_STATUS_OK;
+
+ FM_INFO_REPORT("ste_fm_start_band_scan");
+
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+ if (fm_rds_status) {
+ /* Stop RDS if it is active */
+ result = ste_fm_rds_off();
+ fm_prev_rds_status = STE_TRUE;
+ }
+ result = fmd_rx_scan_band(context, DEFAULT_CHANNELS_TO_SCAN);
+ if (FMD_RESULT_ONGOING != result) {
+ FM_ERR_REPORT("ste_fm_start_band_scan: "
+ "Error Code %d", (unsigned int)result);
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ } else {
+ memset(&ste_fm_rds_info, 0,
+ sizeof(struct ste_fm_rds_info_t));
+ memset(ste_fm_rds_buf, 0,
+ sizeof(struct ste_fm_rds_buf_t) *
+ MAX_RDS_BUFFER * MAX_RDS_GROUPS);
+ result = STE_STATUS_OK;
}
} else {
- FM_ERR_REPORT("ste_fm_set_band: FM not initialized");
+ FM_ERR_REPORT("ste_fm_start_band_scan: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
- FM_DEBUG_REPORT("ste_fm_set_band: returning %s", str_stestatus(result));
+error:
+ FM_DEBUG_REPORT("ste_fm_start_band_scan: returning %s",
+ str_stestatus(result));
return result;
}
-uint8_t ste_fm_step_up_freq(void)
+u8 ste_fm_stop_scan(void)
{
- uint8_t result = STE_STATUS_OK;
+ u8 result = STE_STATUS_OK;
- FM_INFO_REPORT("ste_fm_step_up_freq");
+ FM_INFO_REPORT("ste_fm_stop_scan");
- if (STE_TRUE == fm_init) {
- if (STE_TRUE == fm_power_on && STE_FALSE == fm_stand_by) {
- if (fm_rds_status) {
- /* Stop RDS if it is active */
- result = ste_fm_rds_off();
- fm_prev_rds_status = STE_TRUE;
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+ result = fmd_rx_stop_seeking(context);
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_stop_scan: "
+ "Error Code %d", (unsigned int)result);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ } else {
+ memset(&ste_fm_rds_info, 0,
+ sizeof(struct ste_fm_rds_info_t));
+ memset(ste_fm_rds_buf, 0,
+ sizeof(struct ste_fm_rds_buf_t) *
+ MAX_RDS_BUFFER * MAX_RDS_GROUPS);
+ result = STE_STATUS_OK;
+ if (fm_prev_rds_status) {
+ /* Restart RDS if it was
+ * active earlier */
+ ste_fm_rds_on();
+ fm_prev_rds_status = STE_FALSE;
}
- result = fmd_rx_step_frequency(context, STE_DIR_UP);
- if (result != FMD_RESULT_WAIT) {
- FM_ERR_REPORT("ste_fm_step_up_freq: "\
- "fmd_rx_step_frequency failed %x",
- (unsigned int)result);
- result = STE_STATUS_SYSTEM_ERROR;
- } else {
- /* Wait till cmd is complete */
- os_get_cmd_sem();
- head = 0;
- tail = 0;
- rds_group_sent = 0;
- rds_block_sent = 0;
- memset(ste_fm_rds_buf, 0,
- sizeof(struct ste_fm_rds_buf_s) *
- MAX_RDS_BUFFER *
- MAX_RDS_GROUPS_READ);
- result = STE_STATUS_OK;
- if (fm_prev_rds_status) {
- /* Restart RDS if it was active
- * earlier */
- result = ste_fm_rds_on();
- fm_prev_rds_status = STE_FALSE;
+ }
+ } else {
+ FM_ERR_REPORT("ste_fm_stop_scan: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
+
+error:
+ FM_DEBUG_REPORT("ste_fm_stop_scan: returning %s",
+ str_stestatus(result));
+ return result;
+}
+
+u8 ste_fm_get_scan_result(u16 *num_of_scanfreq,
+ u32 *scan_freq, u32 *scan_freq_rssi_level)
+{
+ u8 result = STE_STATUS_OK;
+ u32 cnt;
+ u32 index;
+ u32 minfreq;
+ u32 maxfreq;
+ u16 channels[3];
+ u16 rssi[3];
+ u8 freq_range;
+ u8 max_channels = 0;
+
+ FM_INFO_REPORT("ste_fm_get_scan_result");
+
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+
+ result = fmd_get_freq_range(context, &freq_range);
+
+ if (STE_STATUS_OK == result)
+ result = fmd_get_freq_range_properties(context,
+ freq_range,
+ &minfreq,
+ &maxfreq);
+ result =
+ fmd_rx_get_max_channels_to_scan(context, &max_channels);
+
+ if (STE_STATUS_OK != result) {
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
+
+ /* In 1 iteration we can retreive max 3 channels */
+ cnt = (max_channels / 3) + 1;
+ while ((cnt--) && (result == FMD_RESULT_SUCCESS)) {
+ /* Get all channels, including empty ones.
+ * In 1 iteration at max 3 channels can be found.
+ */
+ result = fmd_rx_get_scan_band_info(context, cnt * 3,
+ num_of_scanfreq,
+ channels, rssi);
+ if (result == FMD_RESULT_SUCCESS) {
+ index = cnt * 3;
+ /* Convert Freq to Hz from channel number */
+ scan_freq[index] = (minfreq +
+ channels[0] * 50) * 1000;
+ scan_freq_rssi_level[index] = rssi[0];
+ /* Convert Freq to Hz from channel number */
+ scan_freq[index + 1] = (minfreq +
+ channels[1] * 50) *
+ 1000;
+ scan_freq_rssi_level[index + 1] = rssi[1];
+ /* Check if we donot overwrite the array */
+ if (cnt < (max_channels / 3)) {
+ /* Convert Freq to Hz from channel
+ * number */
+ scan_freq[index + 2] =
+ (minfreq + channels[2] * 50) * 1000;
+ scan_freq_rssi_level[index + 2]
+ = rssi[2];
}
}
- } else {
- FM_ERR_REPORT("ste_fm_step_up_freq: "\
- "FM not switched on");
- result = STE_STATUS_SYSTEM_ERROR;
+ }
+ if (fm_prev_rds_status) {
+ /* Restart RDS if it was active earlier */
+ result = ste_fm_rds_on();
+ fm_prev_rds_status = STE_FALSE;
}
} else {
- FM_ERR_REPORT("ste_fm_step_up_freq: FM not initialized");
+ FM_ERR_REPORT("ste_fm_get_scan_result: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
- FM_DEBUG_REPORT("ste_fm_step_up_freq: returning %s",
- str_stestatus(result));
+error:
+ FM_DEBUG_REPORT("ste_fm_get_scan_result: returning %s",
+ str_stestatus(result));
return result;
+
}
-uint8_t ste_fm_step_down_freq(void)
+u8 ste_fm_start_block_scan(void)
{
- uint8_t result = STE_STATUS_OK;
+ u8 result = STE_STATUS_OK;
+ u32 start_freq;
+ u32 end_freq;
+ u8 antenna;
+
+ FM_INFO_REPORT("ste_fm_start_block_scan");
+
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+ if (fm_rds_status) {
+ /* Stop RDS if it is active */
+ result = ste_fm_rds_off();
+ fm_prev_rds_status = STE_TRUE;
+ }
+ start_freq = 87500;
+ end_freq = 90000;
+ result = fmd_get_antenna(context, &antenna);
+ result = fmd_rx_block_scan(context,
+ start_freq, end_freq, antenna);
+ if (FMD_RESULT_ONGOING != result) {
+ FM_ERR_REPORT("ste_fm_start_block_scan: "
+ "Error Code %d", (unsigned int)result);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ } else {
+ memset(&ste_fm_rds_info, 0,
+ sizeof(struct ste_fm_rds_info_t));
+ memset(ste_fm_rds_buf, 0,
+ sizeof(struct ste_fm_rds_buf_t) *
+ MAX_RDS_BUFFER * MAX_RDS_GROUPS);
+ result = STE_STATUS_OK;
+ }
+ } else {
+ FM_ERR_REPORT("ste_fm_start_block_scan: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
- FM_INFO_REPORT("ste_fm_step_down_freq");
+error:
+ FM_DEBUG_REPORT("ste_fm_start_block_scan: returning %s",
+ str_stestatus(result));
+ return result;
+}
- if (STE_TRUE == fm_init) {
- if (STE_TRUE == fm_power_on && STE_FALSE == fm_stand_by) {
- if (fm_rds_status) {
- /* Stop RDS if it is active */
- result = ste_fm_rds_off();
- fm_prev_rds_status = STE_TRUE;
+u8 ste_fm_get_block_scan_result(u16 *num_of_scanchan,
+ u16 *scan_freq_rssi_level)
+{
+ u8 result = STE_STATUS_OK;
+ u32 cnt;
+ u32 index;
+ u16 rssi[6];
+
+ FM_INFO_REPORT("ste_fm_get_block_scan_result");
+
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+ cnt = 33;
+ while ((cnt--) && (result == FMD_RESULT_SUCCESS)) {
+ /* Get all channels, including empty ones */
+ result = fmd_rx_get_block_scan_result(context,
+ cnt * 6,
+ num_of_scanchan,
+ rssi);
+ if (result == FMD_RESULT_SUCCESS) {
+ index = cnt * 6;
+ scan_freq_rssi_level[index]
+ = rssi[0];
+ scan_freq_rssi_level[index + 1]
+ = rssi[1];
+ scan_freq_rssi_level[index + 2]
+ = rssi[2];
+ scan_freq_rssi_level[index + 3]
+ = rssi[3];
+ scan_freq_rssi_level[index + 4]
+ = rssi[4];
+ scan_freq_rssi_level[index + 5]
+ = rssi[5];
+ }
+ }
+ if (STE_FM_RX_MODE == ste_fm_mode) {
+ if (fm_prev_rds_status) {
+ /* Restart RDS if it was
+ * active earlier */
+ result = ste_fm_rds_on();
+ fm_prev_rds_status = STE_FALSE;
}
- result = fmd_rx_step_frequency(context, STE_DIR_DOWN);
- if (result != FMD_RESULT_WAIT) {
- FM_ERR_REPORT("ste_fm_step_down_freq: "\
- "fmd_rx_step_frequency failed %x",
- (unsigned int)result);
+ } else if (STE_FM_TX_MODE == ste_fm_mode) {
+ FM_DEBUG_REPORT("ste_fm_get_block_scan_result:"
+ " Sending Set fmd_tx_set_pa");
+
+ /* Enable the PA */
+ result = fmd_tx_set_pa(context, STE_TRUE);
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_get_block_scan_result:"
+ " fmd_tx_set_pa "
+ "failed %d",
+ (unsigned int)result);
result = STE_STATUS_SYSTEM_ERROR;
- } else {
- /* Wait till cmd is complete */
- os_get_cmd_sem();
- head = 0;
- tail = 0;
- rds_group_sent = 0;
- rds_block_sent = 0;
- memset(ste_fm_rds_buf, 0,
- sizeof(struct ste_fm_rds_buf_s) *
- MAX_RDS_BUFFER *
- MAX_RDS_GROUPS_READ);
- result = STE_STATUS_OK;
- if (fm_prev_rds_status) {
- /* Restart RDS if it was active
- * earlier */
- result = ste_fm_rds_on();
- fm_prev_rds_status = STE_FALSE;
- }
+ goto error;
}
- } else {
- FM_ERR_REPORT("ste_fm_step_down_freq: "\
- "FM not switched on");
- result = STE_STATUS_SYSTEM_ERROR;
}
} else {
- FM_ERR_REPORT("ste_fm_step_down_freq: FM not initialized");
+ FM_ERR_REPORT("ste_fm_get_block_scan_result: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
- FM_DEBUG_REPORT("ste_fm_step_down_freq: returning %s",
- str_stestatus(result));
+error:
+ FM_DEBUG_REPORT("ste_fm_get_block_scan_result: returning %s",
+ str_stestatus(result));
return result;
+
}
-uint8_t ste_fm_search_up_freq(void)
+u8 ste_fm_tx_rds(bool enable_rds)
{
- uint8_t result = STE_STATUS_OK;
+ u8 result = STE_STATUS_OK;
- FM_INFO_REPORT("ste_fm_search_up_freq");
+ FM_INFO_REPORT("ste_fm_tx_rds: enable_rds = %d", enable_rds);
- if (STE_TRUE == fm_init) {
- if (STE_TRUE == fm_power_on && STE_FALSE == fm_stand_by) {
- if (fm_rds_status) {
- /* Stop RDS if it is active */
- result = ste_fm_rds_off();
- fm_prev_rds_status = STE_TRUE;
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+ if (STE_TRUE == enable_rds) {
+ /* Set the Tx Buffer Size */
+ result = fmd_tx_buffer_set_size(context,
+ MAX_RDS_GROUPS - 2);
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_tx_rds: "
+ "fmd_tx_buffer_set_size "
+ "failed %d",
+ (unsigned int)result);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ } else {
+ result = fmd_tx_set_rds(context, STE_TRUE);
}
- result = fmd_rx_seek(context, STE_DIR_UP);
- if (FMD_RESULT_ONGOING != result) {
- FM_ERR_REPORT("ste_fm_search_up_freq: "\
- "Error Code %d", \
- (unsigned int)result);
+
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_tx_rds: "
+ "fmd_tx_set_rds "
+ "failed %d",
+ (unsigned int)result);
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
} else {
- head = 0;
- tail = 0;
- rds_group_sent = 0;
- rds_block_sent = 0;
- memset(ste_fm_rds_buf, 0,
- sizeof(struct ste_fm_rds_buf_s) *
- MAX_RDS_BUFFER *
- MAX_RDS_GROUPS_READ);
- result = STE_STATUS_OK;
+ program_identification_code =
+ default_program_identification_code;
+ program_type_code = default_program_type_code;
+ os_mem_copy(program_service,
+ default_program_service,
+ MAX_PSN_SIZE);
+ os_mem_copy(radio_text,
+ default_radio_text, MAX_RT_SIZE);
+ radio_text[strlen(radio_text)] = 0x0D;
+ ste_fm_transmit_rds_groups();
+ result = STE_STATUS_OK;
}
} else {
- FM_ERR_REPORT("ste_fm_search_up_freq: FM not "\
- "switched on");
+ result = fmd_tx_set_rds(context, STE_FALSE);
+
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_tx_rds: "
+ "fmd_tx_set_rds "
+ "failed %d",
+ (unsigned int)result);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
+ }
+ } else {
+ FM_ERR_REPORT("ste_fm_tx_rds: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
+
+error:
+ FM_DEBUG_REPORT("ste_fm_tx_rds: returning %s", str_stestatus(result));
+
+ return result;
+}
+
+u8 ste_fm_tx_set_pi_code(u16 pi_code)
+{
+ u8 result = STE_STATUS_OK;
+
+ FM_INFO_REPORT("ste_fm_tx_set_pi_code: PI = %04x", pi_code);
+
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+ program_identification_code = pi_code;
+ result = ste_fm_transmit_rds_groups();
+ } else {
+ FM_ERR_REPORT("ste_fm_tx_set_pi_code: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
+
+error:
+ FM_DEBUG_REPORT("ste_fm_tx_set_pi_code: returning %s",
+ str_stestatus(result));
+ return result;
+}
+
+u8 ste_fm_tx_set_pty_code(u16 pty_code)
+{
+ u8 result = STE_STATUS_OK;
+
+ FM_INFO_REPORT("ste_fm_tx_set_pty_code: PI = %04x", pty_code);
+
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+ program_type_code = pty_code;
+ result = ste_fm_transmit_rds_groups();
+ } else {
+ FM_ERR_REPORT("ste_fm_tx_set_pty_code: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
+
+error:
+ FM_DEBUG_REPORT("ste_fm_tx_set_pty_code: returning %s",
+ str_stestatus(result));
+ return result;
+}
+
+u8 ste_fm_tx_set_program_station_name(char *psn, u8 len)
+{
+ u8 result = STE_STATUS_OK;
+
+ FM_INFO_REPORT("ste_fm_tx_set_program_station_name: " "PSN = %s", psn);
+
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+ if (len < (MAX_PSN_SIZE - 1)) {
+ int count = len - 1;
+ while (count < (MAX_PSN_SIZE - 1))
+ psn[count++] = ' ';
+ }
+ memset(program_service, 0, MAX_PSN_SIZE);
+ os_mem_copy(program_service, psn, MAX_PSN_SIZE);
+ result = ste_fm_transmit_rds_groups();
+ } else {
+ FM_ERR_REPORT("ste_fm_tx_set_program_station_name: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
+
+error:
+ FM_DEBUG_REPORT("ste_fm_tx_set_program_station_name: returning %s",
+ str_stestatus(result));
+ return result;
+}
+
+u8 ste_fm_tx_set_radio_text(char *rt, u8 len)
+{
+ u8 result = STE_STATUS_OK;
+
+ FM_INFO_REPORT("ste_fm_tx_set_radio_text: " "RT = %s", rt);
+
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+ rt[len] = 0x0D;
+ memset(radio_text, 0, MAX_RT_SIZE);
+ os_mem_copy(radio_text, rt, len + 1);
+
+ result = ste_fm_transmit_rds_groups();
+ } else {
+ FM_ERR_REPORT("ste_fm_tx_set_radio_text: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
+
+error:
+ FM_DEBUG_REPORT("ste_fm_tx_set_radio_text: returning %s",
+ str_stestatus(result));
+ return result;
+}
+
+u8 ste_fm_tx_get_rds_deviation(u16 *deviation)
+{
+ u8 result = STE_STATUS_OK;
+
+ FM_INFO_REPORT("ste_fm_tx_get_rds_deviation");
+
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+ result = fmd_tx_get_rds_deviation(context, deviation);
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_tx_get_rds_deviation: "
+ "fmd_tx_get_rds_deviation failed %d",
+ (unsigned int)result);
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
} else {
- FM_ERR_REPORT("ste_fm_search_up_freq: FM not initialized");
+ FM_ERR_REPORT("ste_fm_tx_get_rds_deviation: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
- FM_DEBUG_REPORT("ste_fm_search_up_freq: returning %s",
- str_stestatus(result));
+error:
+ FM_DEBUG_REPORT("ste_fm_tx_get_rds_deviation: returning %s",
+ str_stestatus(result));
return result;
}
-uint8_t ste_fm_search_down_freq(void)
+u8 ste_fm_tx_set_rds_deviation(u16 deviation)
{
- uint8_t result = STE_STATUS_OK;
+ u8 result = STE_STATUS_OK;
- FM_INFO_REPORT("ste_fm_search_down_freq");
+ FM_INFO_REPORT("ste_fm_tx_set_rds_deviation: deviation = %d",
+ deviation);
- if (STE_TRUE == fm_init) {
- if (STE_TRUE == fm_power_on && STE_FALSE == fm_stand_by) {
- if (fm_rds_status) {
- /* Stop RDS if it is active */
- result = ste_fm_rds_off();
- fm_prev_rds_status = STE_TRUE;
- }
- result = fmd_rx_seek(context, STE_DIR_DOWN);
- if (FMD_RESULT_ONGOING != result) {
- FM_ERR_REPORT("ste_fm_search_down_freq: "\
- "Error Code %d", \
- (unsigned int)result);
- result = STE_STATUS_SYSTEM_ERROR;
- } else {
- head = 0;
- tail = 0;
- rds_group_sent = 0;
- rds_block_sent = 0;
- memset(ste_fm_rds_buf, 0,
- sizeof(struct ste_fm_rds_buf_s) *
- MAX_RDS_BUFFER *
- MAX_RDS_GROUPS_READ);
- result = STE_STATUS_OK;
- }
- } else {
- FM_ERR_REPORT("ste_fm_search_down_freq: "\
- "FM not switched on");
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+ result = fmd_tx_set_rds_deviation(context, deviation);
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_tx_set_rds_deviation: "
+ "fmd_tx_set_rds_deviation failed %d",
+ (unsigned int)result);
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
} else {
- FM_ERR_REPORT("ste_fm_search_down_freq: FM not initialized");
+ FM_ERR_REPORT("ste_fm_tx_set_rds_deviation: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
- FM_DEBUG_REPORT("ste_fm_search_down_freq: returning %s",
- str_stestatus(result));
+error:
+ FM_DEBUG_REPORT("ste_fm_tx_set_rds_deviation: returning %s",
+ str_stestatus(result));
return result;
}
-uint8_t ste_fm_start_band_scan(void)
+u8 ste_fm_tx_get_pilot_tone_status(bool *enable)
{
- uint8_t result = STE_STATUS_OK;
+ u8 result = STE_STATUS_OK;
- FM_INFO_REPORT("ste_fm_start_band_scan");
+ FM_INFO_REPORT("ste_fm_tx_get_pilot_tone_status");
- if (STE_TRUE == fm_init) {
- if (STE_TRUE == fm_power_on && STE_FALSE == fm_stand_by) {
- if (fm_rds_status) {
- /* Stop RDS if it is active */
- result = ste_fm_rds_off();
- fm_prev_rds_status = STE_TRUE;
- }
- result = fmd_rx_scan_band(context);
- if (FMD_RESULT_ONGOING != result) {
- FM_ERR_REPORT("ste_fm_start_band_scan: "\
- "Error Code %d", \
- (unsigned int)result);
- result = STE_STATUS_SYSTEM_ERROR;
- } else {
- head = 0;
- tail = 0;
- rds_group_sent = 0;
- rds_block_sent = 0;
- memset(ste_fm_rds_buf, 0,
- sizeof(struct ste_fm_rds_buf_s) *
- MAX_RDS_BUFFER *
- MAX_RDS_GROUPS_READ);
- result = STE_STATUS_OK;
- }
- } else {
- FM_ERR_REPORT("ste_fm_start_band_scan: "\
- "FM not switched on");
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+ result = fmd_tx_get_stereo_mode(context, enable);
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_tx_get_pilot_tone_status: "
+ "fmd_tx_get_stereo_mode failed %d",
+ (unsigned int)result);
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
} else {
- FM_ERR_REPORT("ste_fm_start_band_scan: FM not initialized");
+ FM_ERR_REPORT("ste_fm_tx_get_pilot_tone_status: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
- FM_DEBUG_REPORT("ste_fm_start_band_scan: returning %s",
+error:
+ FM_DEBUG_REPORT("ste_fm_tx_get_pilot_tone_status: returning %s",
str_stestatus(result));
return result;
}
-uint8_t ste_fm_stop_scan(void)
+u8 ste_fm_tx_set_pilot_tone_status(bool enable)
{
- uint8_t result = STE_STATUS_OK;
+ u8 result = STE_STATUS_OK;
- FM_INFO_REPORT("ste_fm_stop_scan");
+ FM_INFO_REPORT("ste_fm_tx_set_pilot_tone_status: enable = %d", enable);
- if (STE_TRUE == fm_init) {
- if (STE_TRUE == fm_power_on && STE_FALSE == fm_stand_by) {
- result = fmd_rx_stop_seeking(context);
- if (FMD_RESULT_WAIT != result) {
- FM_ERR_REPORT("ste_fm_stop_scan: "\
- "Error Code %d", (unsigned int)result);
- result = STE_STATUS_SYSTEM_ERROR;
- } else {
- /* Wait till cmd is complete */
- os_get_cmd_sem();
- head = 0;
- tail = 0;
- rds_group_sent = 0;
- rds_block_sent = 0;
- memset(ste_fm_rds_buf, 0,
- sizeof(struct ste_fm_rds_buf_s) *
- MAX_RDS_BUFFER *
- MAX_RDS_GROUPS_READ);
- result = STE_STATUS_OK;
- if (fm_prev_rds_status) {
- /* Restart RDS if it was
- * active earlier */
- ste_fm_rds_on();
- fm_prev_rds_status = STE_FALSE;
- }
- }
- } else {
- FM_ERR_REPORT("ste_fm_stop_scan: FM not switched on");
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+ result = fmd_tx_enable_stereo_mode(context, enable);
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_tx_set_pilot_tone_status: "
+ "fmd_tx_enable_stereo_mode failed %d",
+ (unsigned int)result);
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
} else {
- FM_ERR_REPORT("ste_fm_stop_scan: FM not initialized");
+ FM_ERR_REPORT("ste_fm_tx_set_pilot_tone_status: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
- FM_DEBUG_REPORT("ste_fm_stop_scan: returning %s",
+error:
+ FM_DEBUG_REPORT("ste_fm_tx_set_pilot_tone_status: returning %s",
str_stestatus(result));
return result;
}
-uint8_t ste_fm_get_scan_result(
- uint16_t *no_of_scanfreq,
- uint32_t *scanfreq,
- uint32_t *scanfreq_rssi_level
- )
+u8 ste_fm_tx_get_pilot_deviation(u16 *deviation)
{
- uint8_t result = STE_STATUS_OK;
- uint16_t cnt;
- uint16_t index;
- uint32_t minfreq, maxfreq, freq_interval;
- uint16_t num_of_channels_found = 0;
- uint16_t channels[3];
- uint16_t rssi[3];
+ u8 result = STE_STATUS_OK;
- FM_INFO_REPORT("ste_fm_get_scan_result");
+ FM_INFO_REPORT("ste_fm_tx_get_pilot_deviation");
- if (STE_TRUE == fm_init) {
- if (STE_TRUE == fm_power_on && STE_FALSE == fm_stand_by) {
- result = fmd_get_freq_range_properties(context,
- gfreq_range,
- &minfreq,
- &maxfreq,
- &freq_interval);
-
- cnt = 11;
- while ((cnt--) && (result == FMD_RESULT_SUCCESS)) {
- /* Get all channels, including empty ones */
- result = fmd_rx_get_scan_band_info(
- context, cnt * 3, \
- &num_of_channels_found, channels, rssi);
- if (result == FMD_RESULT_SUCCESS) {
- index = cnt * 3;
- scanfreq[index] = (minfreq +
- channels[0] * 50) * 1000;
- scanfreq_rssi_level[index] = rssi[0];
- scanfreq[index + 1] = (minfreq +
- channels[1] * 50) * 1000;
- scanfreq_rssi_level[index + 1] =
- rssi[1];
- scanfreq[index + 2] = (minfreq +
- channels[2] * 50) * 1000;
- scanfreq_rssi_level[index + 2] =
- rssi[2];
-
- /* store total nr of channels
- * (only once) */
- if (*no_of_scanfreq == 0 &&
- num_of_channels_found > 0) {
- *no_of_scanfreq =
- num_of_channels_found;
- global_event =
- STE_EVENT_SCAN_CHANNELS_FOUND;
- } else if (*no_of_scanfreq == 0
- && num_of_channels_found == 0) {
- global_event =
- STE_EVENT_NO_CHANNELS_FOUND;
- }
- }
- }
- if (fm_prev_rds_status) {
- /* Restart RDS if it was active earlier */
- result = ste_fm_rds_on();
- fm_prev_rds_status = STE_FALSE;
- }
- } else {
- FM_ERR_REPORT("ste_fm_get_scan_result: "\
- "FM not switched on");
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+ result = fmd_tx_get_pilot_deviation(context, deviation);
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_tx_get_pilot_deviation: "
+ "fmd_tx_get_pilot_deviation failed %d",
+ (unsigned int)result);
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
} else {
- FM_ERR_REPORT("ste_fm_get_scan_result: FM not initialized");
+ FM_ERR_REPORT("ste_fm_tx_get_pilot_deviation: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
- FM_DEBUG_REPORT("ste_fm_get_scan_result: returning %s",
- str_stestatus(result));
+error:
+ FM_DEBUG_REPORT("ste_fm_tx_get_pilot_deviation: returning %s",
+ str_stestatus(result));
return result;
+}
+
+u8 ste_fm_tx_set_pilot_deviation(u16 deviation)
+{
+ u8 result = STE_STATUS_OK;
+
+ FM_INFO_REPORT("ste_fm_tx_set_pilot_deviation: deviation = %d",
+ deviation);
+
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+ result = fmd_tx_set_pilot_deviation(context, deviation);
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_tx_set_pilot_deviation: "
+ "fmd_tx_set_pilot_deviation failed %d",
+ (unsigned int)result);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
+ } else {
+ FM_ERR_REPORT("ste_fm_tx_set_pilot_deviation: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
+error:
+ FM_DEBUG_REPORT("ste_fm_tx_set_pilot_deviation: returning %s",
+ str_stestatus(result));
+ return result;
}
-uint8_t ste_fm_increase_volume(void)
+u8 ste_fm_tx_get_preemphasis(u8 *preemphasis)
{
- uint8_t result = STE_STATUS_OK;
- uint8_t vol_in_percentage;
-
- FM_INFO_REPORT("ste_fm_increase_volume");
-
- if (STE_TRUE == fm_init) {
- if (STE_TRUE == fm_power_on && STE_FALSE == fm_stand_by) {
- if (vol_index + 1 < 20) {
- vol_index++;
- vol_in_percentage =
- (uint8_t)(((uint16_t)(vol_index) * 100)/20);
- result =
- fmd_set_volume(context, vol_in_percentage);
- if (FMD_RESULT_SUCCESS != result) {
- FM_DEBUG_REPORT(""\
- "ste_fm_increase_volume: "\
- "FMRSetVolume failed = %d",
- (unsigned int)result);
- result = STE_STATUS_SYSTEM_ERROR;
- }
- } else {
- result = STE_STATUS_OK;
- FM_DEBUG_REPORT("ste_fm_increase_volume: "\
- "Already at max Volume = %d", vol_index);
- }
- if (result != STE_STATUS_OK) {
- /* Reset the volume flag to original value,
- * since API Failed */
- vol_index--;
- }
- } else {
- FM_ERR_REPORT("ste_fm_increase_volume: "\
- "FM not switched on");
+ u8 result = STE_STATUS_OK;
+
+ FM_INFO_REPORT("ste_fm_tx_get_preemphasis");
+
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+ result = fmd_tx_get_preemphasis(context, preemphasis);
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_tx_get_preemphasis: "
+ "fmd_tx_get_preemphasis failed %d",
+ (unsigned int)result);
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
} else {
- FM_ERR_REPORT("ste_fm_increase_volume: FM not initialized");
+ FM_ERR_REPORT("ste_fm_tx_get_preemphasis: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
- FM_DEBUG_REPORT("ste_fm_increase_volume: returning %s",
- str_stestatus(result));
+error:
+ FM_DEBUG_REPORT("ste_fm_tx_get_preemphasis: returning %s",
+ str_stestatus(result));
return result;
}
-uint8_t ste_fm_deccrease_volume(void)
+u8 ste_fm_tx_set_preemphasis(u8 preemphasis)
{
- uint8_t result = STE_STATUS_OK;
- uint8_t vol_in_percentage;
-
- FM_INFO_REPORT("ste_fm_deccrease_volume");
-
- if (STE_TRUE == fm_init) {
- if (STE_TRUE == fm_power_on && STE_FALSE == fm_stand_by) {
- if (vol_index - 1 > 0) {
- vol_index--;
- vol_in_percentage =
- (uint8_t) (((uint16_t)(vol_index) * 100)/20);
- result =
- fmd_set_volume(context, vol_in_percentage);
- if (FMD_RESULT_SUCCESS != result) {
- FM_ERR_REPORT(
- "ste_fm_increase_volume: "\
- "FMRSetVolume failed = %d", \
- (unsigned int) result);
- result = STE_STATUS_SYSTEM_ERROR;
- }
- } else {
- result = STE_STATUS_OK;
- FM_ERR_REPORT("ste_fm_deccrease_volume: "\
- "Already at min Volume = %d",
- vol_index);
- }
- if (result != STE_STATUS_OK) {
- /* Reset the volume flag to original value,
- * since API Failed */
- vol_index++;
- }
- } else {
- FM_ERR_REPORT("ste_fm_deccrease_volume: "\
- "FM not switched on");
+ u8 result = STE_STATUS_OK;
+
+ FM_INFO_REPORT("ste_fm_tx_set_preemphasis: preemphasis = %d",
+ preemphasis);
+
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+ result = fmd_tx_set_preemphasis(context, preemphasis);
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_tx_set_preemphasis: "
+ "fmd_tx_set_preemphasis failed %d",
+ (unsigned int)result);
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
} else {
- FM_ERR_REPORT("ste_fm_deccrease_volume: FM not initialized");
+ FM_ERR_REPORT("ste_fm_tx_set_preemphasis: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
- FM_DEBUG_REPORT("ste_fm_deccrease_volume: returning %s",
- str_stestatus(result));
+error:
+ FM_DEBUG_REPORT("ste_fm_tx_set_preemphasis: returning %s",
+ str_stestatus(result));
return result;
}
-uint8_t ste_fm_set_audio_balance(
- int8_t balance
- )
+u8 ste_fm_tx_get_power_level(u16 *power_level)
{
- uint8_t result = STE_STATUS_OK;
+ u8 result = STE_STATUS_OK;
- FM_INFO_REPORT("ste_fm_set_audio_balance, balance = %d", balance);
+ FM_INFO_REPORT("ste_fm_tx_get_power_level");
- if (STE_TRUE == fm_init) {
- if (STE_TRUE == fm_power_on && STE_FALSE == fm_stand_by) {
- result = fmd_set_balance(context, balance);
- if (FMD_RESULT_SUCCESS != result) {
- FM_ERR_REPORT("FMRSetAudioBalance : "\
- "Failed in fmd_set_balance, err = %d",
- (unsigned int)result);
- result = STE_STATUS_SYSTEM_ERROR;
- }
- } else {
- FM_ERR_REPORT("ste_fm_set_audio_balance: "\
- "FM not switched on");
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+ result = fmd_tx_get_signal_strength(context, power_level);
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_tx_get_power_level: "
+ "fmd_tx_get_signal_strength failed %d",
+ (unsigned int)result);
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
} else {
- FM_ERR_REPORT("ste_fm_set_audio_balance: FM not initialized");
+ FM_ERR_REPORT("ste_fm_tx_get_power_level: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
- FM_DEBUG_REPORT("ste_fm_set_audio_balance: returning %s",
- str_stestatus(result));
+error:
+ FM_DEBUG_REPORT("ste_fm_tx_get_power_level: returning %s",
+ str_stestatus(result));
return result;
}
-uint8_t ste_fm_set_volume(
- uint8_t vol_level
- )
+u8 ste_fm_tx_set_power_level(u16 power_level)
{
- uint8_t result = STE_STATUS_OK;
- uint8_t vol_in_percentage;
+ u8 result = STE_STATUS_OK;
- FM_INFO_REPORT("ste_fm_set_volume: Volume Level = %d", vol_level);
+ FM_INFO_REPORT("ste_fm_tx_set_power_level: power_level = %d",
+ power_level);
- if (STE_TRUE == fm_init) {
- if (STE_TRUE == fm_power_on && STE_FALSE == fm_stand_by) {
- vol_in_percentage = \
- (uint8_t) (((uint16_t)(vol_index) * 100)/20);
- result = fmd_set_volume(context, vol_in_percentage);
- if (FMD_RESULT_SUCCESS != result) {
- FM_ERR_REPORT("ste_fm_increase_volume: "\
- "FMRSetVolume failed, err = %d",
- (unsigned int)result);
- result = STE_STATUS_SYSTEM_ERROR;
- }
- if (STE_STATUS_OK == result)
- vol_index = vol_level;
- } else {
- FM_ERR_REPORT("ste_fm_set_volume: FM not switched on");
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+ result = fmd_tx_set_signal_strength(context, power_level);
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_tx_set_power_level: "
+ "fmd_tx_set_preemphasis failed %d",
+ (unsigned int)result);
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
} else {
- FM_ERR_REPORT("ste_fm_set_volume: FM not initialized");
+ FM_ERR_REPORT("ste_fm_tx_set_power_level: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
- FM_DEBUG_REPORT("ste_fm_set_volume: returning %s",
+error:
+ FM_DEBUG_REPORT("ste_fm_tx_set_power_level: returning %s",
str_stestatus(result));
return result;
}
-uint8_t ste_fm_get_volume(
- uint8_t *vol_level
- )
+u8 ste_fm_set_audio_balance(s8 balance)
{
- uint8_t result = STE_STATUS_OK;
+ u8 result = STE_STATUS_OK;
- FM_INFO_REPORT("ste_fm_get_volume");
+ FM_INFO_REPORT("ste_fm_set_audio_balance, balance = %d", balance);
- if (STE_TRUE == fm_init) {
- if (STE_TRUE == fm_power_on && STE_FALSE == fm_stand_by)
- *vol_level = vol_index;
- else {
- FM_ERR_REPORT("ste_fm_set_volume: FM not switched on");
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+ result = fmd_set_balance(context, balance);
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("FMRSetAudioBalance : "
+ "Failed in fmd_set_balance, err = %d",
+ (unsigned int)result);
result = STE_STATUS_SYSTEM_ERROR;
- *vol_level = 0;
+ goto error;
}
} else {
- FM_ERR_REPORT("ste_fm_set_volume: FM not initialized");
+ FM_ERR_REPORT("ste_fm_set_audio_balance: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
result = STE_STATUS_SYSTEM_ERROR;
- *vol_level = 0;
+ goto error;
}
- FM_DEBUG_REPORT("ste_fm_get_volume: returning %s, VolLevel = %d",
- str_stestatus(result), *vol_level);
+error:
+ FM_DEBUG_REPORT("ste_fm_set_audio_balance: returning %s",
+ str_stestatus(result));
return result;
}
-uint8_t ste_fm_set_audio_dac(
- uint8_t state
- )
+u8 ste_fm_set_volume(u8 vol_level)
{
- uint8_t result = STE_STATUS_OK;
+ u8 result = STE_STATUS_OK;
+ u8 vol_in_percentage;
- FM_INFO_REPORT("ste_fm_set_audio_dac");
+ FM_INFO_REPORT("ste_fm_set_volume: Volume Level = %d", vol_level);
- if (STE_TRUE == fm_init) {
- if (STE_TRUE == fm_power_on && STE_FALSE == fm_stand_by) {
- result = fmd_set_audio_dac(context, state);
- if (FMD_RESULT_SUCCESS != result) {
- FM_ERR_REPORT("ste_fm_set_audio_dac: "\
- "FMRSetAudioDAC failed %d", \
- (unsigned int)result);
- result = STE_STATUS_SYSTEM_ERROR;
- }
- } else {
- FM_ERR_REPORT("ste_fm_set_audio_dac: "\
- "FM not switched on");
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+ vol_in_percentage =
+ (u8) (((u16) (vol_level) * 100) / MAX_ANALOG_VOLUME);
+ result = fmd_set_volume(context, vol_in_percentage);
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_increase_volume: "
+ "FMRSetVolume failed, err = %d",
+ (unsigned int)result);
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
} else {
- FM_ERR_REPORT("ste_fm_set_audio_dac: FM not initialized");
+ FM_ERR_REPORT("ste_fm_set_volume: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
- FM_DEBUG_REPORT("ste_fm_set_audio_dac: "\
- "returning %s", str_stestatus(result));
+error:
+ FM_DEBUG_REPORT("ste_fm_set_volume: returning %s",
+ str_stestatus(result));
return result;
}
-uint8_t ste_fm_rds_off(void)
+u8 ste_fm_get_volume(u8 *vol_level)
{
- uint8_t result = STE_STATUS_OK;
+ u8 result = STE_STATUS_OK;
+
+ FM_INFO_REPORT("ste_fm_get_volume");
+
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+ result = fmd_get_volume(context, vol_level);
+ } else {
+ FM_ERR_REPORT("ste_fm_get_volume: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
+ *vol_level = 0;
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
+
+error:
+ FM_DEBUG_REPORT("ste_fm_get_volume: returning %s, VolLevel = %d",
+ str_stestatus(result), *vol_level);
+ return result;
+}
+
+u8 ste_fm_rds_off(void)
+{
+ u8 result = STE_STATUS_OK;
FM_INFO_REPORT("ste_fm_rds_off");
- if (STE_TRUE == fm_init) {
- if (STE_TRUE == fm_power_on && STE_FALSE == fm_stand_by) {
- result = fmd_rx_set_ctrl(context, FMD_SWITCH_OFF_RDS);
- if (FMD_RESULT_SUCCESS == result) {
- /* Stop the RDS Thread */
- fm_rds_status = STE_FALSE;
- head = 0;
- tail = 0;
- rds_group_sent = 0;
- rds_block_sent = 0;
- memset(ste_fm_rds_buf, 0,
- sizeof(struct ste_fm_rds_buf_s) *
- MAX_RDS_BUFFER *
- MAX_RDS_GROUPS_READ);
- FM_DEBUG_REPORT("ste_fm_rds_off: "\
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+ result = fmd_rx_set_rds(context, FMD_SWITCH_OFF_RDS);
+ if (FMD_RESULT_SUCCESS == result) {
+ /* Stop the RDS Thread */
+ fm_rds_status = STE_FALSE;
+ memset(&ste_fm_rds_info, 0,
+ sizeof(struct ste_fm_rds_info_t));
+ memset(ste_fm_rds_buf, 0,
+ sizeof(struct ste_fm_rds_buf_t) *
+ MAX_RDS_BUFFER * MAX_RDS_GROUPS);
+ FM_DEBUG_REPORT("ste_fm_rds_off: "
"Stopping RDS Thread");
- os_stop_rds_thread();
- }
+ os_stop_rds_thread();
} else {
- FM_ERR_REPORT("ste_fm_rds_off: FM not switched on");
+ FM_ERR_REPORT("ste_fm_rds_off: "
+ "fmd_rx_set_rds failed, err = %d",
+ (unsigned int)result);
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
} else {
- FM_ERR_REPORT("ste_fm_rds_off: FM not initialized");
+ FM_ERR_REPORT("ste_fm_rds_off: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
+error:
FM_DEBUG_REPORT("ste_fm_rds_off: returning %s", str_stestatus(result));
return result;
}
-uint8_t ste_fm_rds_on(void)
+u8 ste_fm_rds_on(void)
{
- uint8_t result = STE_STATUS_OK;
+ u8 result = STE_STATUS_OK;
FM_INFO_REPORT("ste_fm_rds_on");
- if (STE_TRUE == fm_init) {
- if (STE_TRUE == fm_power_on && STE_FALSE == fm_stand_by) {
- FM_DEBUG_REPORT("ste_fm_rds_on:"\
- " Sending fmd_rx_buffer_set_size");
- result = fmd_rx_buffer_set_size(context,
- MAX_RDS_GROUPS_READ);
- if (FMD_RESULT_SUCCESS == result) {
- FM_DEBUG_REPORT("ste_fm_rds_on: "\
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+ FM_DEBUG_REPORT("ste_fm_rds_on:"
+ " Sending fmd_rx_buffer_set_size");
+ result = fmd_rx_buffer_set_size(context, MAX_RDS_GROUPS);
+ if (FMD_RESULT_SUCCESS == result) {
+ FM_DEBUG_REPORT("ste_fm_rds_on: "
"Sending fmd_rx_buffer_set_threshold");
- result = fmd_rx_buffer_set_threshold(context,
- MAX_RDS_GROUPS_READ - 1);
- }
- if (FMD_RESULT_SUCCESS == result) {
- FM_DEBUG_REPORT("ste_fm_rds_on: "\
- "Sending fmd_rx_set_ctrl");
- result = fmd_rx_set_ctrl(context,
+ result = fmd_rx_buffer_set_threshold(context,
+ MAX_RDS_GROUPS -
+ 1);
+ } else {
+ FM_ERR_REPORT("ste_fm_rds_on: "
+ "fmd_rx_buffer_set_size failed, err = %d",
+ (unsigned int)result);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
+ if (FMD_RESULT_SUCCESS == result) {
+ FM_DEBUG_REPORT("ste_fm_rds_on: "
+ "Sending fmd_rx_set_rds");
+ result = fmd_rx_set_rds(context,
FMD_SWITCH_ON_RDS_ENHANCED_MODE);
- }
- if (FMD_RESULT_SUCCESS == result) {
- /* Start the RDS Thread to
- * read the RDS Buffers */
- fm_rds_status = STE_TRUE;
- head = 0;
- tail = 0;
- rds_group_sent = 0;
- rds_block_sent = 0;
- memset(ste_fm_rds_buf, 0,
- sizeof(struct ste_fm_rds_buf_s) *
- MAX_RDS_BUFFER *
- MAX_RDS_GROUPS_READ);
- os_start_rds_thread(ste_fm_rds_callback);
- }
} else {
- FM_ERR_REPORT("ste_fm_rds_on: FM not switched on");
+ FM_ERR_REPORT("ste_fm_rds_on: "
+ "fmd_rx_buffer_set_threshold failed, "
+ "err = %d",
+ (unsigned int)result);
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
+ if (FMD_RESULT_SUCCESS == result) {
+ /* Start the RDS Thread to
+ * read the RDS Buffers */
+ fm_rds_status = STE_TRUE;
+ memset(&ste_fm_rds_info, 0,
+ sizeof(struct ste_fm_rds_info_t));
+ memset(ste_fm_rds_buf, 0,
+ sizeof(struct ste_fm_rds_buf_t) *
+ MAX_RDS_BUFFER * MAX_RDS_GROUPS);
+ os_start_rds_thread(ste_fm_rds_callback);
+ } else {
+ FM_ERR_REPORT("ste_fm_rds_on: "
+ "fmd_rx_set_rds failed, err = %d",
+ (unsigned int)result);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
} else {
- FM_ERR_REPORT("ste_fm_rds_on: FM not initialized");
+ FM_ERR_REPORT("ste_fm_rds_on: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
+error:
FM_DEBUG_REPORT("ste_fm_rds_on: returning %s", str_stestatus(result));
return result;
}
-uint8_t ste_fm_get_rds_status(
- bool *enabled
- )
+u8 ste_fm_get_rds_status(bool *rds_status)
{
- uint8_t result = STE_STATUS_OK;
+ u8 result = STE_STATUS_OK;
FM_INFO_REPORT("ste_fm_get_rds_status");
- if (STE_TRUE == fm_init) {
- if (STE_TRUE == fm_power_on && STE_FALSE == fm_stand_by) {
- result = fmd_rx_get_rds(context, (bool *)enabled);
- if (FMD_RESULT_SUCCESS != result) {
- FM_ERR_REPORT("ste_fm_get_rds_status: "\
- "fmd_rx_get_rds failed %d", \
- (unsigned int)result);
- result = STE_STATUS_SYSTEM_ERROR;
- }
- } else {
- FM_ERR_REPORT("ste_fm_get_rds_status: "\
- "FM not switched on");
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+ if (STE_FM_RX_MODE == ste_fm_mode) {
+ FM_DEBUG_REPORT("ste_fm_get_rds_status: "
+ "fmd_rx_get_rds");
+ result = fmd_rx_get_rds(context, rds_status);
+ } else if (STE_FM_TX_MODE == ste_fm_mode) {
+ FM_DEBUG_REPORT("ste_fm_get_rds_status: "
+ "fmd_tx_get_rds");
+ result = fmd_tx_get_rds(context, rds_status);
+ }
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_get_rds_status: "
+ "fmd_get_rds failed, Error Code %d",
+ (unsigned int)result);
result = STE_STATUS_SYSTEM_ERROR;
- *enabled = STE_FALSE;
+ goto error;
}
} else {
- FM_ERR_REPORT("ste_fm_get_rds_status: FM not initialized");
+ FM_ERR_REPORT("ste_fm_get_rds_status: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
result = STE_STATUS_SYSTEM_ERROR;
- *enabled = STE_FALSE;
+ goto error;
}
- FM_DEBUG_REPORT("ste_fm_get_rds_status: returning %s, RDS Status = %d",
- str_stestatus(result), *enabled);
+error:
+ FM_DEBUG_REPORT("ste_fm_get_rds_status: returning %s, rds_status = %d",
+ str_stestatus(result), *rds_status);
return result;
}
-uint8_t ste_fm_mute(void)
+u8 ste_fm_mute(void)
{
- uint8_t result = STE_STATUS_OK;
+ u8 result = STE_STATUS_OK;
FM_INFO_REPORT("ste_fm_mute");
- if (STE_TRUE == fm_init) {
- if (STE_TRUE == fm_power_on && STE_FALSE == fm_stand_by) {
- /* Mute Analog DAC */
- result = fmd_set_mute(context, STE_TRUE);
- if (FMD_RESULT_WAIT != result) {
- FM_ERR_REPORT("ste_fm_mute: "\
- "fmd_set_mute failed %d", \
- (unsigned int)result);
- result = STE_STATUS_SYSTEM_ERROR;
- } else {
- /* Wait till cmd is complete */
- os_get_cmd_sem();
- /* Mute Ext Src */
- result = fmd_ext_set_mute(context, STE_TRUE);
- result = STE_STATUS_OK;
- /* if (FMD_RESULT_SUCCESS != result)
- result = STE_STATUS_SYSTEM_ERROR; */
- }
- } else {
- FM_ERR_REPORT("ste_fm_mute: FM not switched on");
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+ /* Mute Analog DAC */
+ result = fmd_set_mute(context, STE_TRUE);
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_mute: "
+ "fmd_set_mute failed %d",
+ (unsigned int)result);
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ } else {
+ /* Mute Ext Src */
+ result = fmd_ext_set_mute(context, STE_TRUE);
+ if (FMD_RESULT_SUCCESS != result) {
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
}
} else {
- FM_ERR_REPORT("ste_fm_mute: FM not initialized");
+ FM_ERR_REPORT("ste_fm_mute: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
- FM_DEBUG_REPORT("ste_fm_mute: returning %s",
- str_stestatus(result));
+error:
+ FM_DEBUG_REPORT("ste_fm_mute: returning %s", str_stestatus(result));
return result;
}
-uint8_t ste_fm_unmute(void)
+u8 ste_fm_unmute(void)
{
- uint8_t result = STE_STATUS_OK;
+ u8 result = STE_STATUS_OK;
FM_INFO_REPORT("ste_fm_unmute");
- if (STE_TRUE == fm_init) {
- if (STE_TRUE == fm_power_on && STE_FALSE == fm_stand_by) {
- /* Unmute Analog DAC */
- result = fmd_set_mute(context, STE_FALSE);
- if (FMD_RESULT_WAIT != result) {
- FM_ERR_REPORT("ste_fm_mute: "\
- "fmd_set_mute failed %d", \
- (unsigned int)result);
- result = STE_STATUS_SYSTEM_ERROR;
- } else {
- /* Wait till cmd is complete */
- os_get_cmd_sem();
- /* Unmute Ext Src */
- result = fmd_ext_set_mute(context, STE_FALSE);
- result = STE_STATUS_OK;
- /* if (FMD_RESULT_SUCCESS != result)
- result = STE_STATUS_SYSTEM_ERROR; */
- }
- } else {
- FM_ERR_REPORT("ste_fm_unmute: FM not switched on");
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+ /* Unmute Analog DAC */
+ result = fmd_set_mute(context, STE_FALSE);
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_mute: "
+ "fmd_set_mute failed %d",
+ (unsigned int)result);
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ } else {
+ /* Unmute Ext Src */
+ result = fmd_ext_set_mute(context, STE_FALSE);
+ if (FMD_RESULT_SUCCESS != result) {
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
}
} else {
- FM_ERR_REPORT("ste_fm_unmute: FM not initialized");
+ FM_ERR_REPORT("ste_fm_unmute: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
+error:
FM_DEBUG_REPORT("ste_fm_unmute: returning %s", str_stestatus(result));
return result;
}
-uint8_t ste_fm_get_frequency(
- uint32_t *freq
- )
+u8 ste_fm_get_frequency(u32 *freq)
{
- uint8_t result = STE_STATUS_OK;
- uint32_t currentFreq = 0;
+ u8 result = STE_STATUS_OK;
+ u32 currentFreq = 0;
FM_INFO_REPORT("ste_fm_get_frequency");
- if (STE_TRUE == fm_init) {
- if (STE_TRUE == fm_power_on && STE_FALSE == fm_stand_by) {
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+ if (STE_FM_RX_MODE == ste_fm_mode) {
+ FM_DEBUG_REPORT("ste_fm_get_frequency: "
+ "fmd_rx_get_frequency");
result = fmd_rx_get_frequency(context,
- (uint32_t *)&currentFreq);
- if (FMD_RESULT_SUCCESS != result) {
- result = STE_STATUS_SYSTEM_ERROR;
- FM_ERR_REPORT("ste_fm_get_frequency: "\
- "fmd_rx_get_frequency failed %d", \
- (unsigned int)result);
- }
- if (result == STE_STATUS_OK) {
- /* Convert To Hz */
- *freq = currentFreq * 1000;
- FM_DEBUG_REPORT("ste_fm_get_frequency: "\
- "Current Frequency = %d Hz", *freq);
- if (fm_prev_rds_status) {
- /* Restart RDS if it was
- * active earlier */
- ste_fm_rds_on();
- fm_prev_rds_status = STE_FALSE;
- }
- } else {
- *freq = 0;
- }
- } else {
- FM_ERR_REPORT("ste_fm_get_frequency: "\
- "FM not switched on");
- result = STE_STATUS_SYSTEM_ERROR;
+ (u32 *) &currentFreq);
+ } else if (STE_FM_TX_MODE == ste_fm_mode) {
+ FM_DEBUG_REPORT("ste_fm_get_frequency: "
+ "fmd_tx_get_frequency");
+ result = fmd_tx_get_frequency(context,
+ (u32 *) &currentFreq);
+ }
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_get_frequency: "
+ "fmd_rx_get_frequency failed %d",
+ (unsigned int)result);
*freq = 0;
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ } else {
+ /* Convert To Hz */
+ *freq = currentFreq * 1000;
+ FM_DEBUG_REPORT("ste_fm_get_frequency: "
+ "Current Frequency = %d Hz", *freq);
+ if (fm_prev_rds_status) {
+ /* Restart RDS if it was
+ * active earlier */
+ ste_fm_rds_on();
+ fm_prev_rds_status = STE_FALSE;
+ }
}
} else {
- FM_ERR_REPORT("ste_fm_get_frequency: FM not initialized");
- result = STE_STATUS_SYSTEM_ERROR;
+ FM_ERR_REPORT("ste_fm_get_frequency: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
*freq = 0;
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
- FM_DEBUG_REPORT("ste_fm_get_frequency: "\
- "returning %s", str_stestatus(result));
+error:
+ FM_DEBUG_REPORT("ste_fm_get_frequency: returning %s",
+ str_stestatus(result));
return result;
}
-uint8_t ste_fm_set_frequency(
- uint32_t new_freq
- )
+u8 ste_fm_set_frequency(u32 new_freq)
{
- uint8_t result = STE_STATUS_OK;
+ u8 result = STE_STATUS_OK;
FM_INFO_REPORT("ste_fm_set_frequency, new_freq = %d", (int)new_freq);
- if (STE_TRUE == fm_init) {
- if (STE_TRUE == fm_power_on && STE_FALSE == fm_stand_by) {
- result = fmd_rx_set_frequency(context, new_freq/1000);
- if (result != FMD_RESULT_WAIT) {
- FM_ERR_REPORT("ste_fm_set_frequency: "\
- "fmd_rx_set_frequency failed %x",
- (unsigned int)result);
- result = STE_STATUS_SYSTEM_ERROR;
- } else {
- /* Wait till cmd is complete */
- os_get_cmd_sem();
- head = 0;
- tail = 0;
- rds_group_sent = 0;
- rds_block_sent = 0;
- memset(ste_fm_rds_buf, 0,
- sizeof(struct ste_fm_rds_buf_s) *
- MAX_RDS_BUFFER *
- MAX_RDS_GROUPS_READ);
- result = STE_STATUS_OK;
- }
- } else {
- FM_ERR_REPORT("ste_fm_set_frequency: "\
- "FM not switched on");
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+ if (STE_FM_RX_MODE == ste_fm_mode) {
+ FM_DEBUG_REPORT("ste_fm_set_frequency: "
+ "fmd_rx_set_frequency");
+ result = fmd_rx_set_frequency(context, new_freq / 1000);
+ } else if (STE_FM_TX_MODE == ste_fm_mode) {
+ FM_DEBUG_REPORT("ste_fm_set_frequency: "
+ "fmd_tx_set_frequency");
+ result = fmd_tx_set_frequency(context, new_freq / 1000);
+ }
+ if (result != FMD_RESULT_SUCCESS) {
+ FM_ERR_REPORT("ste_fm_set_frequency: "
+ "fmd_rx_set_frequency failed %x",
+ (unsigned int)result);
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ } else {
+ if (STE_FM_TX_MODE == ste_fm_mode) {
+ FM_DEBUG_REPORT("ste_fm_set_frequency:"
+ " Sending Set" "fmd_tx_set_pa");
+
+ /* Enable the PA */
+ result = fmd_tx_set_pa(context, STE_TRUE);
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_set_frequency:"
+ " fmd_tx_set_pa "
+ "failed %d",
+ (unsigned int)result);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
+ }
+ memset(&ste_fm_rds_info, 0,
+ sizeof(struct ste_fm_rds_info_t));
+ memset(ste_fm_rds_buf, 0,
+ sizeof(struct ste_fm_rds_buf_t) *
+ MAX_RDS_BUFFER * MAX_RDS_GROUPS);
+ result = STE_STATUS_OK;
}
} else {
- FM_ERR_REPORT("ste_fm_set_frequency: "\
- "FM not initialized");
+ FM_ERR_REPORT("ste_fm_set_frequency: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
- FM_DEBUG_REPORT("ste_fm_set_frequency: "\
- "returning %s", str_stestatus(result));
+error:
+ FM_DEBUG_REPORT("ste_fm_set_frequency: returning %s",
+ str_stestatus(result));
return result;
}
-uint8_t ste_fm_get_signal_strength(
- uint16_t *signal_strength
- )
+u8 ste_fm_get_signal_strength(u16 *signal_strength)
{
- uint8_t result = STE_STATUS_OK;
- uint32_t sigStrength = 0;
+ u8 result = STE_STATUS_OK;
FM_INFO_REPORT("ste_fm_get_signal_strength");
- if (STE_TRUE == fm_init) {
- if (STE_TRUE == fm_power_on && STE_FALSE == fm_stand_by) {
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+ if (STE_FM_RX_MODE == ste_fm_mode) {
+ FM_DEBUG_REPORT("ste_fm_get_signal_strength: "
+ "fmd_rx_get_signal_strength");
result = fmd_rx_get_signal_strength(context,
- &sigStrength);
- if (FMD_RESULT_SUCCESS != result) {
- FM_ERR_REPORT("ste_fm_get_signal_strength: "\
- "Error Code %d", (unsigned int)result);
- *signal_strength = 0;
- return STE_STATUS_SYSTEM_ERROR;
- } else
- *signal_strength = sigStrength;
- } else {
- FM_ERR_REPORT("ste_fm_get_signal_strength: "\
- "FM not switched on");
- result = STE_STATUS_SYSTEM_ERROR;
+ signal_strength);
+ } else if (STE_FM_TX_MODE == ste_fm_mode) {
+ FM_DEBUG_REPORT("ste_fm_get_signal_strength: "
+ "fmd_tx_get_signal_strength");
+ result = fmd_tx_get_signal_strength(context,
+ signal_strength);
+ }
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_get_signal_strength: "
+ "Error Code %d", (unsigned int)result);
*signal_strength = 0;
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
} else {
- FM_ERR_REPORT("ste_fm_get_signal_strength: "\
- "FM not initialized");
- result = STE_STATUS_SYSTEM_ERROR;
+ FM_ERR_REPORT("ste_fm_get_signal_strength: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
*signal_strength = 0;
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
+error:
FM_DEBUG_REPORT("ste_fm_get_signal_strength: returning %s",
- str_stestatus(result));
+ str_stestatus(result));
return result;
}
-uint8_t ste_fm_get_mode(
- uint32_t *cur_mode
- )
+u8 ste_fm_af_update_get_result(u16 *af_update_rssi)
{
- uint8_t result = STE_STATUS_OK;
- uint32_t mode;
+ u8 result = STE_STATUS_OK;
+
+ FM_INFO_REPORT("ste_fm_af_update_get_result");
+
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+ result = fmd_rx_get_af_update_result(context, af_update_rssi);
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_af_update_get_result: "
+ "Error Code %d", (unsigned int)result);
+ *af_update_rssi = 0;
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
+ } else {
+ FM_ERR_REPORT("ste_fm_af_update_get_result: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
+ *af_update_rssi = 0;
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
+
+error:
+ FM_DEBUG_REPORT("ste_fm_af_update_get_result: returning %s",
+ str_stestatus(result));
+ return result;
+}
+
+u8 ste_fm_af_update_start(u32 af_freq)
+{
+ u8 result = STE_STATUS_OK;
+
+ FM_INFO_REPORT("ste_fm_af_update_start");
+
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+ result = fmd_rx_af_update_start(context, af_freq / 1000);
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_af_update_start: "
+ "Error Code %d", (unsigned int)result);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
+ } else {
+ FM_ERR_REPORT("ste_fm_af_update_start: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
+
+error:
+ FM_DEBUG_REPORT("ste_fm_af_update_start: returning %s",
+ str_stestatus(result));
+ return result;
+}
+
+u8 ste_fm_af_switch_get_result(u16 *af_switch_conclusion)
+{
+ u8 result = STE_STATUS_OK;
+ u16 af_rssi;
+ u16 af_pi;
+
+ FM_INFO_REPORT("ste_fm_af_switch_get_result");
+
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+ result = fmd_rx_get_af_switch_results(context,
+ af_switch_conclusion,
+ &af_rssi, &af_pi);
+
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_af_switch_get_result: "
+ "Error Code %d", (unsigned int)result);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ } else {
+ FM_DEBUG_REPORT("ste_fm_af_switch_get_result: "
+ "AF Switch conclusion = %d "
+ "AF Switch RSSI level = %d "
+ "AF Switch PI code = %d ",
+ *af_switch_conclusion, af_rssi, af_pi);
+ }
+ } else {
+ FM_ERR_REPORT("ste_fm_af_switch_get_result: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
+
+error:
+ FM_DEBUG_REPORT("ste_fm_af_switch_get_result: returning %s",
+ str_stestatus(result));
+ return result;
+
+}
+
+u8 ste_fm_af_switch_start(u32 af_switch_freq, u16 af_switch_pi)
+{
+ u8 result = STE_STATUS_OK;
+
+ FM_INFO_REPORT("ste_fm_af_switch_start");
+
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+ result = fmd_rx_af_switch_start(context,
+ af_switch_freq / 1000,
+ af_switch_pi);
+
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_af_switch_start: "
+ "Error Code %d", (unsigned int)result);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
+ } else {
+ FM_ERR_REPORT("ste_fm_af_switch_start: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
+
+error:
+ FM_DEBUG_REPORT("ste_fm_af_switch_start: returning %s",
+ str_stestatus(result));
+ return result;
+}
+
+u8 ste_fm_get_mode(u8 *cur_mode)
+{
+ u8 result = STE_STATUS_OK;
+ bool stereo_mode;
FM_INFO_REPORT("ste_fm_get_mode");
- if (STE_TRUE == fm_init) {
- if (STE_TRUE == fm_power_on && STE_FALSE == fm_stand_by) {
- result = fmd_rx_get_stereo_mode(context,
- &mode);
- if (FMD_RESULT_SUCCESS != result) {
- FM_ERR_REPORT("ste_fm_get_mode: "\
- "fmd_rx_get_stereo_mode failed, Error Code %d",
- (unsigned int)result);
- result = STE_STATUS_SYSTEM_ERROR;
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+ if (STE_FM_RX_MODE == ste_fm_mode) {
+ FM_DEBUG_REPORT("ste_fm_get_mode: "
+ "fmd_rx_get_stereo_mode");
+ result = fmd_rx_get_stereo_mode(context, cur_mode);
+ switch (*cur_mode) {
+ case FMD_STEREOMODE_OFF:
+ case FMD_STEREOMODE_BLENDING:
+ *cur_mode = STE_MODE_STEREO;
+ break;
+ case FMD_STEREOMODE_MONO:
+ default:
+ *cur_mode = STE_MODE_MONO;
+ break;
}
- if (result == STE_STATUS_OK)
- *cur_mode = mode;
+ } else if (STE_FM_TX_MODE == ste_fm_mode) {
+ FM_DEBUG_REPORT("ste_fm_get_mode: "
+ "fmd_tx_get_stereo_mode");
+ result = fmd_tx_get_stereo_mode(context, &stereo_mode);
+ if (STE_TRUE == stereo_mode)
+ *cur_mode = STE_MODE_STEREO;
else
- *cur_mode = 0;
- } else {
- FM_ERR_REPORT("ste_fm_get_mode: FM not switched on");
+ *cur_mode = STE_MODE_MONO;
+ }
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_get_mode: "
+ "fmd_get_stereo_mode failed, "
+ "Error Code %d",
+ (unsigned int)result);
result = STE_STATUS_SYSTEM_ERROR;
- *cur_mode = 0;
+ goto error;
}
} else {
- FM_ERR_REPORT("ste_fm_get_mode: FM not initialized");
+ FM_ERR_REPORT("ste_fm_get_mode: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
+ *cur_mode = STE_MODE_MONO;
result = STE_STATUS_SYSTEM_ERROR;
- *cur_mode = 0;
+ goto error;
}
+error:
FM_DEBUG_REPORT("ste_fm_get_mode: returning %s, mode = %d",
- str_stestatus(result), *cur_mode);
+ str_stestatus(result), *cur_mode);
return result;
}
-uint8_t ste_fm_set_mode(
- uint8_t mode
- )
+u8 ste_fm_set_mode(u8 mode)
{
- uint8_t result = STE_STATUS_OK;
+ u8 result = STE_STATUS_OK;
+ bool enable_stereo_mode = STE_FALSE;
FM_INFO_REPORT("ste_fm_set_mode: mode = %d", mode);
- if (STE_TRUE == fm_init) {
- if (STE_TRUE == fm_power_on && STE_FALSE == fm_stand_by) {
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+ if (STE_FM_RX_MODE == ste_fm_mode) {
+ FM_DEBUG_REPORT("ste_fm_set_mode: "
+ "fmd_rx_set_stereo_mode");
result = fmd_rx_set_stereo_mode(context, mode);
- if (FMD_RESULT_SUCCESS != result) {
- FM_ERR_REPORT("ste_fm_set_mode: "\
- "fmd_rx_set_stereo_mode failed, Error Code %d",
- (unsigned int)result);
- result = STE_STATUS_SYSTEM_ERROR;
- }
- } else {
- FM_ERR_REPORT("ste_fm_set_mode: FM not switched on");
+ } else if (STE_FM_TX_MODE == ste_fm_mode) {
+ FM_DEBUG_REPORT("ste_fm_set_mode: "
+ "fmd_tx_set_stereo_mode");
+ if (mode == STE_MODE_STEREO)
+ enable_stereo_mode = STE_TRUE;
+ result =
+ fmd_tx_enable_stereo_mode(context,
+ enable_stereo_mode);
+ }
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_set_mode: "
+ "fmd_rx_set_stereo_mode failed, "
+ "Error Code %d",
+ (unsigned int)result);
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
} else {
- FM_ERR_REPORT("ste_fm_set_mode: FM not initialized");
+ FM_ERR_REPORT("ste_fm_set_mode: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
- FM_DEBUG_REPORT("ste_fm_set_mode: "\
- "returning %s", str_stestatus(result));
+error:
+ FM_DEBUG_REPORT("ste_fm_set_mode: returning %s", str_stestatus(result));
return result;
}
-uint8_t ste_fm_select_antenna(
- uint8_t antenna
- )
+u8 ste_fm_select_antenna(u8 antenna)
{
- uint8_t result = STE_STATUS_OK;
-
- FM_INFO_REPORT("ste_fm_SetAntenna: Antenna = %d", antenna);
-
- if (STE_TRUE == fm_init) {
- if (STE_TRUE == fm_power_on && STE_FALSE == fm_stand_by) {
- result = fmd_set_antenna(context, antenna);
- if (FMD_RESULT_WAIT != result) {
- FM_ERR_REPORT("ste_fm_select_antenna: "\
- "fmd_set_antenna failed, Error Code %d",
- (unsigned int)result);
- result = STE_STATUS_SYSTEM_ERROR;
- } else {
- /* Wait till cmd is complete */
- os_get_cmd_sem();
- result = STE_STATUS_OK;
- }
- } else {
- FM_ERR_REPORT("ste_fm_SetAntenna: FM not switched on");
+ u8 result = STE_STATUS_OK;
+
+ FM_INFO_REPORT("ste_fm_select_antenna: Antenna = %d", antenna);
+
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+ result = fmd_set_antenna(context, antenna);
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_select_antenna: "
+ "fmd_set_antenna failed, Error Code %d",
+ (unsigned int)result);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
+ } else {
+ FM_ERR_REPORT("ste_fm_select_antenna: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
+ }
+
+error:
+ FM_DEBUG_REPORT("ste_fm_select_antenna: returning %s",
+ str_stestatus(result));
+ return result;
+}
+
+u8 ste_fm_get_antenna(u8 *antenna)
+{
+ u8 result = STE_STATUS_OK;
+
+ FM_INFO_REPORT("ste_fm_get_antenna");
+
+ if (STE_FM_STATE_SWITCHED_ON == ste_fm_state) {
+ result = fmd_get_antenna(context, antenna);
+ if (FMD_RESULT_SUCCESS != result) {
+ FM_ERR_REPORT("ste_fm_get_antenna: "
+ "fmd_get_antenna failed, Error Code %d",
+ (unsigned int)result);
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
} else {
- FM_ERR_REPORT("ste_fm_SetAntenna: FM not initialized");
+ FM_ERR_REPORT("ste_fm_get_antenna: "
+ "Invalid state of FM Driver = %d", ste_fm_state);
result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
- FM_DEBUG_REPORT("ste_fm_SetAntenna: "\
- "returning %s", str_stestatus(result));
+error:
+ FM_DEBUG_REPORT("ste_fm_get_antenna: returning %s",
+ str_stestatus(result));
return result;
}
-uint8_t ste_fm_get_rssi_threshold(
- uint16_t *rssi_thresold
- )
+u8 ste_fm_get_rssi_threshold(u16 *rssi_thresold)
{
- uint8_t result = STE_STATUS_OK;
+ u8 result = STE_STATUS_OK;
FM_INFO_REPORT("ste_fm_get_rssi_threshold");
result = fmd_rx_get_stop_level(context, rssi_thresold);
if (FMD_RESULT_SUCCESS != result) {
- FM_ERR_REPORT("ste_fm_get_rssi_threshold: "\
- "fmd_rx_get_stop_level failed, Error Code %d",
- (unsigned int)result);
- result = STE_STATUS_SYSTEM_ERROR;
+ FM_ERR_REPORT("ste_fm_get_rssi_threshold: "
+ "fmd_rx_get_stop_level failed, Error Code %d",
+ (unsigned int)result);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
+error:
FM_DEBUG_REPORT("ste_fm_get_rssi_threshold: returning %s",
- str_stestatus(result));
+ str_stestatus(result));
return result;
}
-uint8_t ste_fm_set_rssi_threshold(
- uint16_t rssi_thresold
- )
+u8 ste_fm_set_rssi_threshold(u16 rssi_thresold)
{
- uint8_t result = STE_STATUS_OK;
+ u8 result = STE_STATUS_OK;
- FM_INFO_REPORT("ste_fm_set_rssi_threshold: "\
- "RssiThresold = %d", rssi_thresold);
+ FM_INFO_REPORT("ste_fm_set_rssi_threshold: "
+ "RssiThresold = %d", rssi_thresold);
result = fmd_rx_set_stop_level(context, rssi_thresold);
if (FMD_RESULT_SUCCESS != result) {
- FM_ERR_REPORT("ste_fm_set_rssi_threshold: "\
- "fmd_rx_set_stop_level failed, Error Code %d",
- (unsigned int)result);
- result = STE_STATUS_SYSTEM_ERROR;
+ FM_ERR_REPORT("ste_fm_set_rssi_threshold: "
+ "fmd_rx_set_stop_level failed, Error Code %d",
+ (unsigned int)result);
+ result = STE_STATUS_SYSTEM_ERROR;
+ goto error;
}
+error:
FM_DEBUG_REPORT("ste_fm_set_rssi_threshold: returning %s",
- str_stestatus(result));
+ str_stestatus(result));
return result;
}
MODULE_AUTHOR("Hemant Gupta");
MODULE_LICENSE("GPL v2");
-
diff --git a/drivers/media/radio/CG2900/stefmapi.h b/drivers/media/radio/CG2900/stefmapi.h
index 3fc277ddf84..d9147bb257a 100755
--- a/drivers/media/radio/CG2900/stefmapi.h
+++ b/drivers/media/radio/CG2900/stefmapi.h
@@ -1,6 +1,4 @@
/*
- * file stefmapi.h
- *
* Copyright (C) ST-Ericsson SA 2010
*
* Linux FM Host API's for ST-Ericsson FM Chip.
@@ -19,7 +17,7 @@
typedef void (*ste_fm_rds_cb)(void);
/**
- * struct ste_fm_rds_buf_s - RDS Group Receiving Structure
+ * struct ste_fm_rds_buf_t - RDS Group Receiving Structure
* @block1: RDS Block A
* @block2: RDS Block B
* @block3: RDS Block C
@@ -32,76 +30,171 @@ typedef void (*ste_fm_rds_cb)(void);
* Structure for receiving the RDS Group from FM Chip.
*
*/
-struct ste_fm_rds_buf_s {
- uint16_t block1;
- uint16_t block2;
- uint16_t block3;
- uint16_t block4;
- uint8_t status1;
- uint8_t status2;
- uint8_t status3;
- uint8_t status4;
+struct ste_fm_rds_buf_t {
+ u16 block1;
+ u16 block2;
+ u16 block3;
+ u16 block4;
+ u8 status1;
+ u8 status2;
+ u8 status3;
+ u8 status4;
};
-#define STE_TRUE 1
-#define STE_FALSE 0
+/**
+ * struct ste_fm_rds_info_t - RDS Information Structure
+ * @rds_head: RDS Queue Head for storing next valid data.
+ * @rds_tail: RDS Queue Tail for retreiving next valid data.
+ * @rds_group_sent: Number of RDS Groups sent to Application.
+ * @rds_block_sent: Number of RDS Blocks sent to Application.
+ *
+ * Structure for storing the RDS data queue information.
+ *
+ */
+struct ste_fm_rds_info_t {
+ u8 rds_head;
+ u8 rds_tail;
+ u8 rds_group_sent;
+ u8 rds_block_sent;
+};
-#define STE_STATUS_OK 0
-#define STE_STATUS_SYSTEM_ERROR 1
-#define STE_STATUS_BUSY_ERROR 2
-#define STE_STATUS_SEARCH_NO_CHANNEL_FOUND 3
-#define STE_STATUS_SCAN_NO_CHANNEL_FOUND 4
+/**
+ * enum ste_fm_flags_t - FM API Flags
+ * @STE_FALSE: Equivalent to boolean false.
+ * @STE_TRUE: Equivalent to boolean true.
+ * FM API Flags.
+ */
+enum ste_fm_flags_t {
+ STE_FALSE,
+ STE_TRUE
+};
-#define STE_FM_BAND_US_EU 0
-#define STE_FM_BAND_CHINA 1
-#define STE_FM_BAND_JAPAN 2
-#define STE_FM_BAND_CUSTOM 3
+/**
+ * enum ste_fm_status_t - Status codes returned by FM API Layer.
+ * @STE_STATUS_OK: No Error.
+ * @STE_STATUS_SYSTEM_ERROR: Error occurred in last operation.
+ * Various Status codes returned by FM API Layer.
+ */
+enum ste_fm_status_t {
+ STE_STATUS_OK,
+ STE_STATUS_SYSTEM_ERROR
+};
-#define STE_FM_GRID_50 0
-#define STE_FM_GRID_100 1
-#define STE_FM_GRID_200 2
+/**
+ * enum ste_fm_state_t - States of FM Driver.
+ * @STE_FM_STATE_DEINITIALIZED: FM driver is not initialized.
+ * @STE_FM_STATE_INITIALIZED: FM driver is initialized.
+ * @STE_FM_STATE_SWITCHED_ON: FM driver is switched on and in active state.
+ * @STE_FM_STATE_STAND_BY: FM Radio is switched on but not in active state.
+ * Various states of FM Driver.
+ */
+enum ste_fm_state_t {
+ STE_FM_STATE_DEINITIALIZED,
+ STE_FM_STATE_INITIALIZED,
+ STE_FM_STATE_SWITCHED_ON,
+ STE_FM_STATE_STAND_BY
+} ;
-#define STE_EVENT_NO_EVENT 1
-#define STE_EVENT_SEARCH_CHANNEL_FOUND 2
-#define STE_EVENT_SCAN_CHANNELS_FOUND 3
-#define STE_EVENT_NO_CHANNELS_FOUND 4
+/**
+ * enum fmd_gocmd_t - FM Driver Command state .
+ * @STE_FM_IDLE_MODE: FM Radio is in Idle Mode.
+ * @STE_FM_RX_MODE: FM Radio is configured in Rx mode.
+ * @STE_FM_TX_MODE: FM Radio is configured in Tx mode.
+ * Various Modes of the FM Radio.
+ */
+enum ste_fm_mode_t {
+ STE_FM_IDLE_MODE,
+ STE_FM_RX_MODE,
+ STE_FM_TX_MODE
+};
-#define STE_FM_DEEMPHASIS_OFF 0
-#define STE_FM_DEEMPHASIS_50us 1
-#define STE_FM_DEEMPHASIS_75us 2
+/**
+ * enum ste_fm_band_t - Various Frequency band supported.
+ * @STE_FM_BAND_US_EU: European / US Band.
+ * @STE_FM_BAND_JAPAN: Japan Band.
+ * @STE_FM_BAND_CHINA: China Band.
+ * @STE_FM_BAND_CUSTOM: Custom Band.
+ * Various Frequency band supported.
+ */
+enum ste_fm_band_t {
+ STE_FM_BAND_US_EU,
+ STE_FM_BAND_JAPAN,
+ STE_FM_BAND_CHINA,
+ STE_FM_BAND_CUSTOM
+};
-#define STE_DIR_DOWN 0
-#define STE_DIR_UP 1
+/**
+ * enum ste_fm_band_t - Various Frequency grids supported.
+ * @STE_FM_GRID_50: 50 kHz spacing.
+ * @STE_FM_GRID_100: 100 kHz spacing.
+ * @STE_FM_GRID_200: 200 kHz spacing.
+ * Various Frequency grids supported.
+ */
+enum ste_fm_grid_t {
+ STE_FM_GRID_50,
+ STE_FM_GRID_100,
+ STE_FM_GRID_200
+};
-#define STE_FM_DAC_OFF 0
-#define STE_FM_DAC_ON 1
-#define STE_FM_DAC_LEFT_ONLY 2
-#define STE_FM_DAC_RIGHT_ONLY 3
+/**
+ * enum ste_fm_event_t - Various Events reported by FM API layer.
+ * @STE_EVENT_NO_EVENT: No Event.
+ * @STE_EVENT_SEARCH_CHANNEL_FOUND: Seek operation is completed.
+ * @STE_EVENT_SCAN_CHANNELS_FOUND: Band Scan is completed.
+ * @STE_EVENT_BLOCK_SCAN_CHANNELS_FOUND: Block Scan is completed.
+ * @STE_EVENT_SCAN_CANCELLED: Scan/Seek is cancelled.
+ * Various Events reported by FM API layer.
+ */
+enum ste_fm_event_t {
+ STE_EVENT_NO_EVENT,
+ STE_EVENT_SEARCH_CHANNEL_FOUND,
+ STE_EVENT_SCAN_CHANNELS_FOUND,
+ STE_EVENT_BLOCK_SCAN_CHANNELS_FOUND,
+ STE_EVENT_SCAN_CANCELLED
+};
-#define STE_STEREO_MODE_STEREO 0
-#define STE_STEREO_MODE_FORCE_MONO 1
-#define STE_STEREO_MODE_BLENDING 2
-#define STE_STEREO_MODE_SWITCHING 3
+/**
+ * enum ste_fm_direction_t - Directions used while seek.
+ * @STE_DIR_DOWN: Search in downwards direction.
+ * @STE_DIR_UP: Search in upwards direction.
+ * Directions used while seek.
+ */
+enum ste_fm_direction_t {
+ STE_DIR_DOWN,
+ STE_DIR_UP
+};
-#define STE_AFSWITCH_SUCCEEDED 0
-#define STE_AFSWITCH_FAIL_LOW_RSSI 1
-#define STE_AFSWITCH_FAIL_WRONG_PI 2
-#define STE_AFSWITCH_FAIL_NO_RDS 3
+/**
+ * enum ste_fm_stereo_mode_t - Stereo Modes.
+ * @STE_MODE_MONO: Mono Mode.
+ * @STE_MODE_STEREO: Stereo Mode.
+ * Stereo Modes.
+ */
+enum ste_fm_stereo_mode_t {
+ STE_MODE_MONO,
+ STE_MODE_STEREO
+};
#define STE_FM_DEFAULT_RSSI_THRESHOLD 100
#define MAX_RDS_BUFFER 10
-#define MAX_RDS_GROUPS_READ 22
+#define MAX_RDS_GROUPS 22
+#define MIN_ANALOG_VOLUME 0
+#define MAX_ANALOG_VOLUME 20
#define NUM_OF_RDS_BLOCKS 4
+#define RDS_BLOCK_MASK 0x1C
+#define RDS_ERROR_STATUS_MASK 0x03
+#define RDS_UPTO_TWO_BITS_CORRECTED 0x01
+#define RDS_UPTO_FIVE_BITS_CORRECTED 0x02
+#define MAX_RT_SIZE 65
+#define MAX_PSN_SIZE 9
+#define DEFAULT_CHANNELS_TO_SCAN 32
+#define MAX_CHANNELS_TO_SCAN 99
+#define MAX_CHANNELS_FOR_BLOCK_SCAN 198
-extern uint8_t global_event;
-extern uint8_t rds_buf_count;
-extern uint8_t head;
-extern uint8_t tail;
-extern uint8_t rds_group_sent;
-extern uint8_t rds_block_sent;
-extern struct ste_fm_rds_buf_s\
- ste_fm_rds_buf[MAX_RDS_BUFFER][MAX_RDS_GROUPS_READ];
+extern u8 global_event;
+extern struct ste_fm_rds_buf_t ste_fm_rds_buf[MAX_RDS_BUFFER][MAX_RDS_GROUPS];
+extern struct ste_fm_rds_info_t ste_fm_rds_info;
/**
* ste_fm_init()- Initializes FM Radio.
@@ -113,36 +206,30 @@ extern struct ste_fm_rds_buf_s\
* STE_STATUS_OK, if Initialization successful
* STE_STATUS_SYSTEM_ERROR, otherwise.
*/
-uint8_t ste_fm_init(void);
+u8 ste_fm_init(void);
/**
* ste_fm_deinit()- De-initializes FM Radio.
* De-initializes the Variables and structures required for FM Driver.
*
* Returns:
- * STE_STATUS_OK, if operation completed successfully.
+ * STE_STATUS_OK, if operation completed successfully.
* STE_STATUS_SYSTEM_ERROR, otherwise.
*/
-uint8_t ste_fm_deinit(void);
+u8 ste_fm_deinit(void);
/**
* ste_fm_switch_on()- Start up procedure of the FM radio.
- * @device: Pointer to char device requesting the operation.
- * @freq: Frequency in Hz to be set on the FM Radio.
- * @band: Band To be Set.
- * (0: US/EU, 1: Japan, 2: China, 3: Custom)
- * @grid: Grid specifying Spacing.
- * (0: 50 KHz, 1: 100 KHz, 2: 200 Khz)
+ * @device: Character device requesting the operation.
*
* Returns:
* STE_STATUS_OK, if operation completed successfully.
* STE_STATUS_SYSTEM_ERROR, otherwise.
*/
-uint8_t ste_fm_switch_on(
- struct device *device,
- uint32_t freq,
- uint8_t band,
- uint8_t grid);
+u8 ste_fm_switch_on(
+ struct device *device
+ );
+
/**
* ste_fm_switch_off()- Switches off FM radio
@@ -151,7 +238,7 @@ uint8_t ste_fm_switch_on(
* STE_STATUS_OK, if operation completed successfully.
* STE_STATUS_SYSTEM_ERROR, otherwise.
*/
-uint8_t ste_fm_switch_off(void);
+u8 ste_fm_switch_off(void);
/**
* ste_fm_standby()- Makes the FM Radio Go in Standby mode.
@@ -163,7 +250,7 @@ uint8_t ste_fm_switch_off(void);
* STE_STATUS_OK, if operation completed successfully.
* STE_STATUS_SYSTEM_ERROR, otherwise.
*/
-uint8_t ste_fm_standby(void);
+u8 ste_fm_standby(void);
/**
* ste_fm_power_up_from_standby()- Power Up FM Radio from Standby mode.
@@ -174,53 +261,77 @@ uint8_t ste_fm_standby(void);
* STE_STATUS_OK, if operation completed successfully.
* STE_STATUS_SYSTEM_ERROR, otherwise.
*/
-uint8_t ste_fm_power_up_from_standby(void);
+u8 ste_fm_power_up_from_standby(void);
/**
- * ste_fm_set_grid()- Sets the Grid on the FM Radio.
+ * ste_fm_set_rx_default_settings()- Loads FM Rx Default Settings.
+ * @freq: Frequency in Hz to be set on the FM Radio.
+ * @band: Band To be Set.
+ * (0: US/EU, 1: Japan, 2: China, 3: Custom)
* @grid: Grid specifying Spacing.
- * (0: 50 KHz,1: 100 KHz,2: 200 Khz)
+ * (0: 50 KHz, 1: 100 KHz, 2: 200 Khz)
+ * @enable_rds: Flag indicating enable or disable rds transmission.
+ * @enable_stereo: Flag indicating enable or disable stereo mode.
*
* Returns:
* STE_STATUS_OK, if operation completed successfully.
* STE_STATUS_SYSTEM_ERROR, otherwise.
*/
-uint8_t ste_fm_set_grid(
- uint8_t grid
+u8 ste_fm_set_rx_default_settings(
+ u32 freq,
+ u8 band,
+ u8 grid,
+ bool enable_rds,
+ bool enable_stereo
);
/**
- * ste_fm_set_band()- Sets the Band on the FM Radio.
- * @band: Band specifying Region.
- * (0: US_EU,1: Japan,2: China,3: Custom)
+ * ste_fm_set_tx_default_settings()- Loads FM Tx Default Settings.
+ * @freq: Frequency in Hz to be set on the FM Radio.
+ * @band: Band To be Set.
+ * (0: US/EU, 1: Japan, 2: China, 3: Custom)
+ * @grid: Grid specifying Spacing.
+ * (0: 50 KHz, 1: 100 KHz, 2: 200 Khz)
+ * @enable_rds: Flag indicating enable or disable rds transmission.
+ * @enable_stereo: Flag indicating enable or disable stereo mode.
*
* Returns:
* STE_STATUS_OK, if operation completed successfully.
* STE_STATUS_SYSTEM_ERROR, otherwise.
*/
-uint8_t ste_fm_set_band(
- uint8_t band
+u8 ste_fm_set_tx_default_settings(
+ u32 freq,
+ u8 band,
+ u8 grid,
+ bool enable_rds,
+ bool enable_stereo
);
/**
- * ste_fm_step_up_freq()- Steps Up Current Frequency.
- * Steps up the frequency depending on the Grid
+ * ste_fm_set_grid()- Sets the Grid on the FM Radio.
+ * @grid: Grid specifying Spacing.
+ * (0: 50 KHz,1: 100 KHz,2: 200 Khz)
*
* Returns:
* STE_STATUS_OK, if operation completed successfully.
* STE_STATUS_SYSTEM_ERROR, otherwise.
*/
-uint8_t ste_fm_step_up_freq(void);
+u8 ste_fm_set_grid(
+ u8 grid
+ );
/**
- * ste_fm_step_down_freq()- Steps Down Current Frequency.
- * Steps down the frequency depending on the Grid
+ * ste_fm_set_band()- Sets the Band on the FM Radio.
+ * @band: Band specifying Region.
+ * (0: US_EU,1: Japan,2: China,3: Custom)
*
* Returns:
* STE_STATUS_OK, if operation completed successfully.
* STE_STATUS_SYSTEM_ERROR, otherwise.
*/
-uint8_t ste_fm_step_down_freq(void);
+u8 ste_fm_set_band(
+ u8 band
+ );
/**
* ste_fm_search_up_freq()- seek Up.
@@ -239,7 +350,7 @@ uint8_t ste_fm_step_down_freq(void);
* STE_STATUS_OK, if operation started successfully.
* STE_STATUS_SYSTEM_ERROR, otherwise.
*/
-uint8_t ste_fm_search_up_freq(void);
+u8 ste_fm_search_up_freq(void);
/**
* ste_fm_search_down_freq()- seek Down.
@@ -257,7 +368,7 @@ uint8_t ste_fm_search_up_freq(void);
* STE_STATUS_OK, if operation started successfully.
* STE_STATUS_SYSTEM_ERROR, otherwise.
*/
-uint8_t ste_fm_search_down_freq(void);
+u8 ste_fm_search_down_freq(void);
/**
* ste_fm_start_band_scan()- Band Scan.
@@ -267,17 +378,18 @@ uint8_t ste_fm_search_down_freq(void);
* If the operation is started successfully, the chip will generate
* the irpt_OperationSucced. interrupt when the operation is completed.
* After completion the chip will still be tuned the original station before
- * starting the Scan. on reception of interrupt, the host should call the API
- * ste_fm_get_scan_result() to retrieve the Stations and corresponding RSSI of
- * stations found in the Band.
+ * starting the Scan. on reception of interrupt, the host should call the AP
+ * ste_fm_get_scan_result() to retrieve the Stations and corresponding
+ * RSSI of stations found in the Band.
* Till the interrupt is received, no more API's should be called
- * except ste_fm_stop_scan.
+ * except ste_fm_stop_scan, ste_fm_switch_off, ste_fm_standby and
+ * ste_fm_get_frequency.
*
* Returns:
* STE_STATUS_OK, if operation started successfully.
* STE_STATUS_SYSTEM_ERROR, otherwise.
*/
-uint8_t ste_fm_start_band_scan(void);
+u8 ste_fm_start_band_scan(void);
/**
* ste_fm_stop_scan()- Stops an active ongoing seek or Band Scan.
@@ -290,96 +402,300 @@ uint8_t ste_fm_start_band_scan(void);
* STE_STATUS_OK, if operation started successfully.
* STE_STATUS_SYSTEM_ERROR, otherwise.
*/
-uint8_t ste_fm_stop_scan(void);
+u8 ste_fm_stop_scan(void);
/**
* ste_fm_get_scan_result()- Retreives Band Scan Result
* Retrieves the Scan Band Results of the stations found and
* the corressponding RSSI values of the stations.
- * @no_of_scanfreq: (out) Pointer to Number of Stations found
+ * @num_of_scanfreq: (out) Number of Stations found
* during Scanning.
- * @scanfreq: (out) Pointer to Frequency of Stations in Hz
+ * @scan_freq: (out) Frequency of Stations in Hz
* found during Scanning.
- * @scanfreq_rssi_level: (out) Pointer to RSSI level of Stations
+ * @scan_freq_rssi_level: (out) RSSI level of Stations
* found during Scanning.
*
* Returns:
* STE_STATUS_OK, if operation completed successfully.
* STE_STATUS_SYSTEM_ERROR, otherwise.
*/
-uint8_t ste_fm_get_scan_result(
- uint16_t *no_of_scanfreq,
- uint32_t *scanfreq,
- uint32_t *scanfreq_rssi_level);
+u8 ste_fm_get_scan_result(
+ u16 *num_of_scanfreq,
+ u32 *scan_freq,
+ u32 *scan_freq_rssi_level
+ );
/**
- * ste_fm_increase_volume()- Increases the Analog Out Gain of Chip.
- * Maximum level of Gain is 20.
+ * ste_fm_start_block_scan()- Block Scan.
+ *
+ * Searches for RSSI level of all the channels between the start and stop
+ * channels. If the operation is started successfully, the chip will generate
+ * the irpt_OperationSucced interrupt when the operation is completed.
+ * After completion the chip will still be tuned the original station before
+ * starting the Scan. On reception of interrupt, the host should call the AP
+ * ste_fm_get_block_scan_result() to retrieve the RSSI of channels.
+ * Till the interrupt is received, no more API's should be called from Host
+ * except ste_fm_stop_scan, ste_fm_switch_off, ste_fm_standby and
+ * ste_fm_get_frequency.
+ *
+ * Returns:
+ * STE_STATUS_OK, if operation started successfully.
+ * STE_STATUS_SYSTEM_ERROR, otherwise.
+ */
+u8 ste_fm_start_block_scan(void);
+
+/**
+ * ste_fm_get_scan_result()- Retreives Band Scan Result
+ * Retrieves the Scan Band Results of the stations found and
+ * the corressponding RSSI values of the stations.
+ * @num_of_scanchan: (out) Number of Stations found
+ * during Scanning.
+ * @scan_freq_rssi_level: (out) RSSI level of Stations
+ * found during Scanning.
*
* Returns:
* STE_STATUS_OK, if operation completed successfully.
* STE_STATUS_SYSTEM_ERROR, otherwise.
*/
-uint8_t ste_fm_increase_volume(void);
+u8 ste_fm_get_block_scan_result(
+ u16 *num_of_scanchan,
+ u16 *scan_freq_rssi_level
+ );
/**
- * ste_fm_deccrease_volume()- Decreases the Analog Out Gain of Chip.
- * Minimum level of Gain is 0.
+ * ste_fm_tx_get_rds_deviation()- Gets RDS Deviation.
+ * Retrieves the RDS Deviation level set for FM Tx.
+ * @deviation: (out) Rds Deviation.
*
* Returns:
* STE_STATUS_OK, if operation completed successfully.
* STE_STATUS_SYSTEM_ERROR, otherwise.
*/
-uint8_t ste_fm_deccrease_volume(void);
+u8 ste_fm_tx_get_rds_deviation(
+ u16 *deviation
+ );
/**
- * ste_fm_set_audio_balance()- Sets Audio Balance.
- * @balance: Audio Balnce to be Set in Percentage.
- * (-100: Right Mute.... 0: Both on.... 100: Left Mute)
+ * ste_fm_tx_set_rds_deviation()- Sets RDS Deviation.
+ * Sets the RDS Deviation level on FM Tx.
+ * @deviation: Rds Deviation to set on FM Tx.
*
* Returns:
* STE_STATUS_OK, if operation completed successfully.
* STE_STATUS_SYSTEM_ERROR, otherwise.
*/
-uint8_t ste_fm_set_audio_balance(
- int8_t balance
+u8 ste_fm_tx_set_rds_deviation(
+ u16 deviation
);
/**
- * ste_fm_set_volume()- Sets the Analog Out Gain of FM Chip.
- * @vol_level: Volume Level to be set on Tuner (0-20).
+ * ste_fm_tx_set_pi_code()- Sets PI code for RDS Transmission.
+ * Sets the Program Identification code to be transmitted.
+ * @pi_code: PI code to be transmitted.
*
* Returns:
* STE_STATUS_OK, if operation completed successfully.
* STE_STATUS_SYSTEM_ERROR, otherwise.
*/
-uint8_t ste_fm_set_volume(
- uint8_t vol_level
+u8 ste_fm_tx_set_pi_code(
+ u16 pi_code
);
/**
- * ste_fm_set_volume()- Gets the currently set Analog Out Gain of FM Chip.
- * @vol_level: (out)Volume Level set on Tuner (0-20).
+ * ste_fm_tx_set_pty_code()- Sets PTY code for RDS Transmission.
+ * Sets the Program Type code to be transmitted.
+ * @pty_code: PTY code to be transmitted.
*
* Returns:
* STE_STATUS_OK, if operation completed successfully.
* STE_STATUS_SYSTEM_ERROR, otherwise.
*/
-uint8_t ste_fm_get_volume(
- uint8_t *vol_level
+u8 ste_fm_tx_set_pty_code(
+ u16 pty_code
);
/**
- * ste_fm_set_audio_dac()- Set Audio DAC state on FM chip
- * @state: state: Audio DAC state to be Set.
- * (0: Disabled, 1: Enabled,2: Right Mute, 3: Left Mute)
+ * ste_fm_tx_set_program_station_name()- Sets PSN for RDS Transmission.
+ * Sets the Program Station Name to be transmitted.
+ * @psn: Program Station Name to be transmitted.
+ * @len: Length of Program Station Name to be transmitted.
*
* Returns:
* STE_STATUS_OK, if operation completed successfully.
* STE_STATUS_SYSTEM_ERROR, otherwise.
*/
-uint8_t ste_fm_set_audio_dac(
- uint8_t state
+u8 ste_fm_tx_set_program_station_name(
+ char *psn,
+ u8 len
+ );
+
+/**
+ * ste_fm_tx_set_radio_text()- Sets RT for RDS Transmission.
+ * Sets the radio text to be transmitted.
+ * @rt: Radio Text to be transmitted.
+ * @len: Length of Radio Text to be transmitted.
+ *
+ * Returns:
+ * STE_STATUS_OK, if operation completed successfully.
+ * STE_STATUS_SYSTEM_ERROR, otherwise.
+ */
+u8 ste_fm_tx_set_radio_text(
+ char *rt,
+ u8 len
+ );
+
+/**
+ * ste_fm_tx_get_rds_deviation()- Gets Pilot Tone status
+ * Gets the current status of pilot tone for FM Tx.
+ * @enable: (out) Flag indicating Pilot Tone is enabled or disabled.
+ *
+ * Returns:
+ * STE_STATUS_OK, if operation completed successfully.
+ * STE_STATUS_SYSTEM_ERROR, otherwise.
+ */
+u8 ste_fm_tx_get_pilot_tone_status(
+ bool *enable
+ );
+
+/**
+ * ste_fm_tx_set_pilot_tone_status()- Enables/Disables Pilot Tone.
+ * Enables or disables the pilot tone for FM Tx.
+ * @enable: Flag indicating enabling or disabling Pilot Tone.
+ *
+ * Returns:
+ * STE_STATUS_OK, if operation completed successfully.
+ * STE_STATUS_SYSTEM_ERROR, otherwise.
+ */
+u8 ste_fm_tx_set_pilot_tone_status(
+ bool enable
+ );
+
+/**
+ * ste_fm_tx_get_pilot_deviation()- Gets Pilot Deviation.
+ * Retrieves the Pilot Tone Deviation level set for FM Tx.
+ * @deviation: (out) Pilot Tone Deviation.
+ *
+ * Returns:
+ * STE_STATUS_OK, if operation completed successfully.
+ * STE_STATUS_SYSTEM_ERROR, otherwise.
+ */
+u8 ste_fm_tx_get_pilot_deviation(
+ u16 *deviation
+ );
+
+/**
+ * ste_fm_tx_set_pilot_deviation()- Sets Pilot Deviation.
+ * Sets the Pilot Tone Deviation level on FM Tx.
+ * @deviation: Pilot Tone Deviation to set.
+ *
+ * Returns:
+ * STE_STATUS_OK, if operation completed successfully.
+ * STE_STATUS_SYSTEM_ERROR, otherwise.
+ */
+u8 ste_fm_tx_set_pilot_deviation(
+ u16 deviation
+ );
+
+/**
+ * ste_fm_tx_get_preemphasis()- Gets Pre-emhasis level.
+ * Retrieves the Preemphasis level set for FM Tx.
+ * @preemphasis: (out) Preemphasis level.
+ *
+ * Returns:
+ * STE_STATUS_OK, if operation completed successfully.
+ * STE_STATUS_SYSTEM_ERROR, otherwise.
+ */
+u8 ste_fm_tx_get_preemphasis(
+ u8 *preemphasis
+ );
+
+/**
+ * ste_fm_tx_set_preemphasis()- Sets Pre-emhasis level.
+ * Sets the Preemphasis level on FM Tx.
+ * @preemphasis: Preemphasis level.
+ *
+ * Returns:
+ * STE_STATUS_OK, if operation completed successfully.
+ * STE_STATUS_SYSTEM_ERROR, otherwise.
+ */
+u8 ste_fm_tx_set_preemphasis(
+ u8 preemphasis
+ );
+
+/**
+ * ste_fm_tx_get_power_level()- Gets Power level.
+ * Retrieves the Power level set for FM Tx.
+ * @power_level: (out) Power level.
+ *
+ * Returns:
+ * STE_STATUS_OK, if operation completed successfully.
+ * STE_STATUS_SYSTEM_ERROR, otherwise.
+ */
+u8 ste_fm_tx_get_power_level(
+ u16 *power_level
+ );
+
+/**
+ * ste_fm_tx_set_power_level()- Sets Power level.
+ * Sets the Power level for FM Tx.
+ * @power_level: Power level.
+ *
+ * Returns:
+ * STE_STATUS_OK, if operation completed successfully.
+ * STE_STATUS_SYSTEM_ERROR, otherwise.
+ */
+u8 ste_fm_tx_set_power_level(
+ u16 power_level
+ );
+
+/**
+ * ste_fm_tx_rds()- Enable or disable Tx RDS.
+ * Enable or disable RDS transmission.
+ * @enable_rds: Flag indicating enabling or disabling RDS.
+ *
+ * Returns:
+ * STE_STATUS_OK, if operation completed successfully.
+ * STE_STATUS_SYSTEM_ERROR, otherwise.
+ */
+u8 ste_fm_tx_rds(
+ bool enable_rds
+ );
+
+/**
+ * ste_fm_set_audio_balance()- Sets Audio Balance.
+ * @balance: Audio Balnce to be Set in Percentage.
+ * (-100: Right Mute.... 0: Both on.... 100: Left Mute)
+ *
+ * Returns:
+ * STE_STATUS_OK, if operation completed successfully.
+ * STE_STATUS_SYSTEM_ERROR, otherwise.
+ */
+u8 ste_fm_set_audio_balance(
+ s8 balance
+ );
+
+/**
+ * ste_fm_set_volume()- Sets the Analog Out Gain of FM Chip.
+ * @vol_level: Volume Level to be set on Tuner (0-20).
+ *
+ * Returns:
+ * STE_STATUS_OK, if operation completed successfully.
+ * STE_STATUS_SYSTEM_ERROR, otherwise.
+ */
+u8 ste_fm_set_volume(
+ u8 vol_level
+ );
+
+/**
+ * ste_fm_get_volume()- Gets the currently set Analog Out Gain of FM Chip.
+ * @vol_level: (out)Volume Level set on Tuner (0-20).
+ *
+ * Returns:
+ * STE_STATUS_OK, if operation completed successfully.
+ * STE_STATUS_SYSTEM_ERROR, otherwise.
+ */
+u8 ste_fm_get_volume(
+ u8 *vol_level
);
/**
@@ -389,7 +705,7 @@ uint8_t ste_fm_set_audio_dac(
* STE_STATUS_OK, if operation completed successfully.
* STE_STATUS_SYSTEM_ERROR, otherwise.
*/
-uint8_t ste_fm_rds_off(void);
+u8 ste_fm_rds_off(void);
/**
* ste_fm_rds_on()- Enables the RDS decoding algorithm in FM chip
@@ -398,18 +714,18 @@ uint8_t ste_fm_rds_off(void);
* STE_STATUS_OK, if operation completed successfully.
* STE_STATUS_SYSTEM_ERROR, otherwise.
*/
-uint8_t ste_fm_rds_on(void);
+u8 ste_fm_rds_on(void);
/**
* ste_fm_get_rds_status()- Retrieves the status whether RDS is enabled or not
- * @enabled: (out) Pointer to the status of RDS
+ * @rds_status: (out) Status of RDS
*
* Returns:
* STE_STATUS_OK, if operation completed successfully.
* STE_STATUS_SYSTEM_ERROR, otherwise.
*/
-uint8_t ste_fm_get_rds_status(
- bool *enabled
+u8 ste_fm_get_rds_status(
+ bool *rds_status
);
/**
@@ -419,7 +735,7 @@ uint8_t ste_fm_get_rds_status(
* STE_STATUS_OK, if operation completed successfully.
* STE_STATUS_SYSTEM_ERROR, otherwise.
*/
-uint8_t ste_fm_mute(void);
+u8 ste_fm_mute(void);
/**
* ste_fm_unmute()- Unmutes the Audio output from FM Chip
@@ -428,56 +744,108 @@ uint8_t ste_fm_mute(void);
* STE_STATUS_OK, if operation completed successfully.
* STE_STATUS_SYSTEM_ERROR, otherwise.
*/
-uint8_t ste_fm_unmute(void);
+u8 ste_fm_unmute(void);
/**
* ste_fm_get_frequency()- Gets the Curently tuned Frequency on FM Radio
- * @freq: (out) Pointer to Frequency in Hz set on the FM Radio.
+ * @freq: (out) Frequency in Hz set on the FM Radio.
*
* Returns:
* STE_STATUS_OK, if operation completed successfully.
* STE_STATUS_SYSTEM_ERROR, otherwise.
*/
-uint8_t ste_fm_get_frequency(
- uint32_t *freq
+u8 ste_fm_get_frequency(
+ u32 *freq
);
/**
- * ste_fm_set_frequency()- Gets the Curently tuned Frequency on FM Radio
+ * ste_fm_set_frequency()- Sets the frequency on FM Radio
* @new_freq: Frequency in Hz to be set on the FM Radio.
*
* Returns:
* STE_STATUS_OK, if operation completed successfully.
* STE_STATUS_SYSTEM_ERROR, otherwise.
*/
-uint8_t ste_fm_set_frequency(
- uint32_t new_freq
+u8 ste_fm_set_frequency(
+ u32 new_freq
);
/**
- * ste_fm_set_frequency()- Gets the Curently tuned Frequency on FM Radio
- * @signal_strength: (out) Pointer to the RSSI level of the currently
+ * ste_fm_get_signal_strength()- Gets the RSSI level.
+ * @signal_strength: (out) RSSI level of the currently
* tuned frequency.
*
* Returns:
* STE_STATUS_OK, if operation completed successfully.
* STE_STATUS_SYSTEM_ERROR, otherwise.
*/
-uint8_t ste_fm_get_signal_strength(
- uint16_t *signal_strength
+u8 ste_fm_get_signal_strength(
+ u16 *signal_strength
+ );
+
+/**
+ * ste_fm_get_af_updat()- Retrives results of AF Update
+ * @af_update_rssi: (out) RSSI level of the Alternative frequency.
+ *
+ * Returns:
+ * STE_STATUS_OK, if operation completed successfully.
+ * STE_STATUS_SYSTEM_ERROR, otherwise.
+ */
+u8 ste_fm_af_update_get_result(
+ u16 *af_update_rssi
+ );
+
+
+/**
+ * ste_fm_af_update_start()- PErforms AF Update.
+ * @af_freq: AF frequency in Hz whose RSSI is to be retrived.
+ * tuned frequency.
+ *
+ * Returns:
+ * STE_STATUS_OK, if operation completed successfully.
+ * STE_STATUS_SYSTEM_ERROR, otherwise.
+ */
+
+u8 ste_fm_af_update_start(
+ u32 af_freq
+ );
+
+/**
+ * ste_fm_af_switch_get_result()- Retrives the AF switch result.
+ * @af_switch_conclusion: (out) Conclusion of the AF Switch.
+ *
+ * Returns:
+ * STE_STATUS_OK, if operation completed successfully.
+ * STE_STATUS_SYSTEM_ERROR, otherwise.
+ */
+u8 ste_fm_af_switch_get_result(
+ u16 *af_switch_conclusion
+ );
+
+/**
+ * ste_fm_af_switch_start()- PErforms AF switch.
+ * @af_switch_freq: Alternate Frequency in Hz to be switched.
+ * @af_switch_pi: picode of the Alternative frequency.
+ * Returns:
+ * STE_STATUS_OK, if operation completed successfully.
+ * STE_STATUS_SYSTEM_ERROR, otherwise.
+ */
+u8 ste_fm_af_switch_start(
+ u32 af_switch_freq,
+ u16 af_switch_pi
);
/**
* ste_fm_get_mode()- Gets the mode of the Radio tuner.
- * @cur_mode: (out) Pointer to the current mode set on FM Radio
+ * @cur_mode: (out) Current mode set on FM Radio
* (0: Stereo, 1: Mono, 2: Blending, 3: Switching).
*
* Returns:
* STE_STATUS_OK, if operation completed successfully.
* STE_STATUS_SYSTEM_ERROR, otherwise.
*/
-uint8_t ste_fm_get_mode(
- uint32_t *cur_mode
+u8 ste_fm_get_mode(
+ u8 *cur_mode
);
/**
@@ -489,8 +857,8 @@ uint8_t ste_fm_get_mode(
* STE_STATUS_OK, if operation completed successfully.
* STE_STATUS_SYSTEM_ERROR, otherwise.
*/
-uint8_t ste_fm_set_mode(
- uint8_t mode
+u8 ste_fm_set_mode(
+ u8 mode
);
/**
@@ -501,21 +869,33 @@ uint8_t ste_fm_set_mode(
* STE_STATUS_OK, if operation completed successfully.
* STE_STATUS_SYSTEM_ERROR, otherwise.
*/
-uint8_t ste_fm_select_antenna(
- uint8_t antenna
+u8 ste_fm_select_antenna(
+ u8 antenna
+ );
+
+/**
+ * ste_fm_get_antenna()- Retreives the currently selected antenna.
+ * @antenna: out (0: Embedded, 1: Wired.)
+ *
+ * Returns:
+ * STE_STATUS_OK, if operation completed successfully.
+ * STE_STATUS_SYSTEM_ERROR, otherwise.
+ */
+u8 ste_fm_get_antenna(
+ u8 *antenna
);
/**
* ste_fm_get_rssi_threshold()- Gets the rssi threshold currently
* set on FM radio.
- * @rssi_thresold: (out) Pointer to Current rssi threshold set.
+ * @rssi_thresold: (out) Current rssi threshold set.
*
* Returns:
* STE_STATUS_OK, if operation completed successfully.
* STE_STATUS_SYSTEM_ERROR, otherwise.
*/
-uint8_t ste_fm_get_rssi_threshold(
- uint16_t *rssi_thresold
+u8 ste_fm_get_rssi_threshold(
+ u16 *rssi_thresold
);
/**
@@ -527,8 +907,8 @@ uint8_t ste_fm_get_rssi_threshold(
* STE_STATUS_OK, if operation completed successfully.
* STE_STATUS_SYSTEM_ERROR, otherwise.
*/
-uint8_t ste_fm_set_rssi_threshold(
- uint16_t rssi_thresold
+u8 ste_fm_set_rssi_threshold(
+ u16 rssi_thresold
);
/**
@@ -537,5 +917,10 @@ uint8_t ste_fm_set_rssi_threshold(
*/
void wake_up_poll_queue(void);
-
+/**
+ * void wake_up_read_queue()- Wakes up the Task waiting on Read Queue.
+ * This function is called when RDS data is available for reading by
+ * application.
+ */
+void wake_up_read_queue(void);
#endif /* STE_FM_API_H */
diff --git a/firmware/R1e2v10BT_src_coeff_11.fw.org b/firmware/BT_src_coeff_1.1.fw.org
index 83549331be2..83549331be2 100755
--- a/firmware/R1e2v10BT_src_coeff_11.fw.org
+++ b/firmware/BT_src_coeff_1.1.fw.org
Binary files differ
diff --git a/firmware/Cobra_FM_SOC1_coef.fw.org b/firmware/Cobra_FM_SOC1_coef.fw.org
new file mode 100755
index 00000000000..90a89b86f5d
--- /dev/null
+++ b/firmware/Cobra_FM_SOC1_coef.fw.org
Binary files differ
diff --git a/firmware/Cobra_FM_SOC1_prog.fw.org b/firmware/Cobra_FM_SOC1_prog.fw.org
new file mode 100755
index 00000000000..91cef21b81c
--- /dev/null
+++ b/firmware/Cobra_FM_SOC1_prog.fw.org
Binary files differ
diff --git a/firmware/R1e2v10EXT_src_coeff_11.fw.org b/firmware/EXT_src_coeff_1.1.fw.org
index 875380e2c4a..875380e2c4a 100755
--- a/firmware/R1e2v10EXT_src_coeff_11.fw.org
+++ b/firmware/EXT_src_coeff_1.1.fw.org
Binary files differ
diff --git a/firmware/Makefile b/firmware/Makefile
index 4a4a12a283f..e21859c0605 100644
--- a/firmware/Makefile
+++ b/firmware/Makefile
@@ -144,8 +144,8 @@ fw-shipped-$(CONFIG_MFD_STE_CONN) += ste_conn_patch_info.fw ste_conn_settings_in
fw-shipped-$(CONFIG_RADIO_CG2900) += ste_fm_bt_src_coeff_info.fw ste_fm_ext_src_coeff_info.fw \
ste_fm_fm_coeff_info.fw ste_fm_fm_prog_info.fw \
- R1e2v10BT_src_coeff_11.fw R1e2v10FM_coeff.fw \
- R1e2v10FM_prog.fw R1e2v10EXT_src_coeff_11.fw
+ BT_src_coeff_1.1.fw EXT_src_coeff_1.1.fw \
+ Cobra_FM_SOC1_coef.fw Cobra_FM_SOC1_prog.fw
fw-shipped-all := $(fw-shipped-y) $(fw-shipped-m) $(fw-shipped-)
diff --git a/firmware/R1e2v10FM_coeff.fw.org b/firmware/R1e2v10FM_coeff.fw.org
deleted file mode 100755
index f56218e721a..00000000000
--- a/firmware/R1e2v10FM_coeff.fw.org
+++ /dev/null
Binary files differ
diff --git a/firmware/R1e2v10FM_prog.fw.org b/firmware/R1e2v10FM_prog.fw.org
deleted file mode 100755
index c4c9e518b34..00000000000
--- a/firmware/R1e2v10FM_prog.fw.org
+++ /dev/null
Binary files differ
diff --git a/firmware/ste_fm_bt_src_coeff_info.fw.org b/firmware/ste_fm_bt_src_coeff_info.fw.org
index 3d163bbf198..ee155dbdd5e 100755..100644
--- a/firmware/ste_fm_bt_src_coeff_info.fw.org
+++ b/firmware/ste_fm_bt_src_coeff_info.fw.org
@@ -1,13 +1,17 @@
+#########################################################################
+# ST-Ericsson Connectivity Chip FM BT Coeffecient Information File
#
-# FM BT Coeffecient File
+# All information must be stored as follows
#
-# All Coeffecient information must be stored as follows
+# HCI_revision LMP_Subversion File_name (without .org extension)
#
-# CHIP_ID HCI_revision LMP_Subversion
+########################################################################
#
-# ST: <CHIP_ID> is set to 0x00000000 since this is not used by ST.
#
-# FM Coeffecient file for ST-Ericsson - CG2900
+########################################################################
#
-0x0700 0x0011 R1e2v10BT_src_coeff_11.fw
+# FM BT Coeffecient file for ST-Ericsson - CG2900
#
+0x0700 0x0011 BT_src_coeff_1.1.fw
+#
+########################################################################
diff --git a/firmware/ste_fm_ext_src_coeff_info.fw.org b/firmware/ste_fm_ext_src_coeff_info.fw.org
index 48be3dedb78..3a6ac5e3c54 100755..100644
--- a/firmware/ste_fm_ext_src_coeff_info.fw.org
+++ b/firmware/ste_fm_ext_src_coeff_info.fw.org
@@ -1,13 +1,17 @@
+#########################################################################
+# ST-Ericsson Connectivity Chip FM Ext Coeffecient Information File
#
-# FM Ext Coeffecient File
+# All information must be stored as follows
#
-# All Coeffecient information must be stored as follows
+# HCI_revision LMP_Subversion File_name (without .org extension)
#
-# CHIP_ID HCI_revision LMP_Subversion
+########################################################################
#
-# ST: <CHIP_ID> is set to 0x00000000 since this is not used by ST.
#
-# FM Coeffecient file for ST-Ericsson - CG2900
+########################################################################
#
-0x0700 0x0011 R1e2v10EXT_src_coeff_11.fw
+# FM Ext Coeffecient file for ST-Ericsson - CG2900
#
+0x0700 0x0011 EXT_src_coeff_1.1.fw
+#
+########################################################################
diff --git a/firmware/ste_fm_fm_coeff_info.fw.org b/firmware/ste_fm_fm_coeff_info.fw.org
index 631ac1ca818..03bfb783797 100755..100644
--- a/firmware/ste_fm_fm_coeff_info.fw.org
+++ b/firmware/ste_fm_fm_coeff_info.fw.org
@@ -1,13 +1,17 @@
+#########################################################################
+# ST-Ericsson Connectivity Chip FM Coeffecient Information File
#
-# FM Coeffecient File
+# All information must be stored as follows
#
-# All Coeffecient information must be stored as follows
+# HCI_revision LMP_Subversion File_name (without .org extension)
#
-# CHIP_ID HCI_revision LMP_Subversion
+########################################################################
#
-# ST: <CHIP_ID> is set to 0x00000000 since this is not used by ST.
+#
+########################################################################
#
# FM Coeffecient file for ST-Ericsson - CG2900
#
-0x0700 0x0011 R1e2v10FM_coeff.fw
+0x0700 0x0011 Cobra_FM_SOC1_coef.fw
#
+#########################################################################
diff --git a/firmware/ste_fm_fm_prog_info.fw.org b/firmware/ste_fm_fm_prog_info.fw.org
index 3872ac0acbf..b5920eaeadf 100755..100644
--- a/firmware/ste_fm_fm_prog_info.fw.org
+++ b/firmware/ste_fm_fm_prog_info.fw.org
@@ -1,13 +1,17 @@
+#########################################################################
+# ST-Ericsson Connectivity Chip FM Firmware Information File
#
-# FM Firmware File
+# All information must be stored as follows
#
-# All firmware information must be stored as follows
+# HCI_revision LMP_Subversion File_name (without .org extension)
#
-# CHIP_ID HCI_revision LMP_Subversion
+########################################################################
#
-# ST: <CHIP_ID> is set to 0x00000000 since this is not used by ST.
+#
+########################################################################
#
# FM Firmware file for ST-Ericsson - CG2900
#
-0x0700 0x0011 R1e2v10FM_prog.fw
+0x0700 0x0011 Cobra_FM_SOC1_prog.fw
#
+##########################################################################