コード例 #1
0
static long Si47xx_ioctl(struct file *filp, unsigned int ioctl_cmd,
							unsigned long arg)
{
	long ret = 0;
	void __user *argp = (void __user *)arg;

	debug("Si47xx ioctl 0x%x", ioctl_cmd);

	if (_IOC_TYPE(ioctl_cmd) != Si47xx_IOC_MAGIC) {
		debug("Inappropriate ioctl 1 0x%x", ioctl_cmd);
		return -ENOTTY;
	}

	if (_IOC_NR(ioctl_cmd) > Si47xx_IOC_NR_MAX) {
		debug("Inappropriate ioctl 2 0x%x", ioctl_cmd);
		return -ENOTTY;
	}

	switch (ioctl_cmd) {
	case Si47xx_IOC_POWERUP:
		debug("Si47xx_IOC_POWERUP called\n\n");

		ret = (long)Si47xx_dev_powerup();
		if (ret < 0)
			debug("Si47xx_IOC_POWERUP failed\n");
		break;

	case Si47xx_IOC_POWERDOWN:
		debug("Si47xx_IOC_POWERDOWN called\n");

		ret = (long)Si47xx_dev_powerdown();
		if (ret < 0)
			debug("Si47xx_IOC_POWERDOWN failed\n");
		break;

	case Si47xx_IOC_BAND_SET:
		{
			int band;
			debug("Si47xx_IOC_BAND_SET called\n\n");

			if (copy_from_user((void *)&band, argp, sizeof(int)))
				ret = -EFAULT;
			else {
				ret = (long)Si47xx_dev_band_set(band);
				if (ret < 0)
					debug("Si47xx_IOC_BAND_SET failed\n");
			}
		}
		break;

	case Si47xx_IOC_CHAN_SPACING_SET:
		{
			int ch_spacing;
			debug("Si47xx_IOC_CHAN_SPACING_SET called\n");

			if (copy_from_user
			    ((void *)&ch_spacing, argp, sizeof(int)))
				ret = -EFAULT;
			else {
			ret = (long)Si47xx_dev_ch_spacing_set(ch_spacing);
				if (ret < 0)
					debug("Si47xx_IOC_CHAN_SPACING_SET "
						"failed\n");
			}
		}
		break;

	case Si47xx_IOC_CHAN_SELECT:
		{
			u32 frequency;
			debug("Si47xx_IOC_CHAN_SELECT called\n");

			if (copy_from_user
			    ((void *)&frequency, argp, sizeof(u32)))
				ret = -EFAULT;
			else {
				ret = (long)Si47xx_dev_chan_select(frequency);
				if (ret < 0)
					debug("Si47xx_IOC_CHAN_SELECT "
					"failed\n");
			}
		}
		break;

	case Si47xx_IOC_CHAN_GET:
		{
			u32 frequency = 0;
			debug("Si47xx_IOC_CHAN_GET called\n");

			ret = (long)Si47xx_dev_chan_get(&frequency);
			if (ret < 0)
				debug("Si47xx_IOC_CHAN_GET failed\n");
			else if (copy_to_user
				 (argp, (void *)&frequency, sizeof(u32)))
				ret = -EFAULT;
		}
		break;

	case Si47xx_IOC_SEEK_FULL:
		{
			u32 frequency = 0;
			debug("Si47xx_IOC_SEEK_FULL called\n");

			ret = (long)Si47xx_dev_seek_full(&frequency);
			if (ret < 0)
				debug("Si47xx_IOC_SEEK_FULL failed\n");
			else if (copy_to_user
				 (argp, (void *)&frequency, sizeof(u32)))
				ret = -EFAULT;
		}
		break;

	case Si47xx_IOC_SEEK_UP:
		{
			u32 frequency = 0;
			debug("Si47xx_IOC_SEEK_UP called\n");

			ret = (long)Si47xx_dev_seek_up(&frequency);
			if (ret < 0)
				debug("Si47xx_IOC_SEEK_UP failed\n");
			else if (copy_to_user
				 (argp, (void *)&frequency, sizeof(u32)))
				ret = -EFAULT;
		}
		break;

	case Si47xx_IOC_SEEK_DOWN:
		{
			u32 frequency = 0;
			debug("Si47xx_IOC_SEEK_DOWN called\n");

			ret = (long)Si47xx_dev_seek_down(&frequency);
			if (ret < 0)
				debug("Si47xx_IOC_SEEK_DOWN failed\n");
			else if (copy_to_user
				 (argp, (void *)&frequency, sizeof(u32)))
				ret = -EFAULT;
		}
		break;

	case Si47xx_IOC_RSSI_SEEK_TH_SET:
		{
			u8 RSSI_seek_th;
			debug("Si47xx_IOC_RSSI_SEEK_TH_SET called\n");

			if (copy_from_user
			    ((void *)&RSSI_seek_th, argp, sizeof(u8)))
				ret = -EFAULT;
			else {
			ret = (long)Si47xx_dev_RSSI_seek_th_set(RSSI_seek_th);
				if (ret < 0)
					debug("Si47xx_IOC_RSSI_SEEK_TH_SET "
						       "failed\n");
			}
		}
		break;

	case Si47xx_IOC_SEEK_SNR_SET:
		{
			u8 seek_SNR_th;
			debug("Si47xx_IOC_SEEK_SNR_SET called\n");

			if (copy_from_user
			    ((void *)&seek_SNR_th, argp, sizeof(u8)))
				ret = -EFAULT;
			else {
			ret = (long)Si47xx_dev_seek_SNR_th_set(seek_SNR_th);
				if (ret < 0)
					debug("Si47xx_IOC_SEEK_SNR_SET "
					"failed\n");
			}
		}
		break;

	case Si47xx_IOC_SEEK_CNT_SET:
		{
			u8 seek_FM_ID_th;
			debug("Si47xx_IOC_SEEK_CNT_SET called\n");

			if (copy_from_user
			    ((void *)&seek_FM_ID_th, argp, sizeof(u8)))
				ret = -EFAULT;
			else {
				ret =
			(long)Si47xx_dev_seek_FM_ID_th_set(seek_FM_ID_th);
				if (ret < 0)
					debug("Si47xx_IOC_SEEK_CNT_SET "
					"failed\n");
			}
		}
		break;

	case Si47xx_IOC_CUR_RSSI_GET:
		{
			struct rssi_snr_t data;
			debug("Si47xx_IOC_CUR_RSSI_GET called\n");

			ret = (long)Si47xx_dev_cur_RSSI_get(&data);
			if (ret < 0)
				debug("Si47xx_IOC_CUR_RSSI_GET failed\n");
			else if (copy_to_user(argp, (void *)&data,
					      sizeof(data)))
				ret = -EFAULT;

			debug("curr_rssi:%d\ncurr_rssi_th:%d\ncurr_snr:%d\n",
			      data.curr_rssi, data.curr_rssi_th, data.curr_snr);
		}
		break;

	case Si47xx_IOC_VOLUME_SET:
		{
			u8 volume;
			if (copy_from_user((void *)&volume, argp, sizeof(u8)))
				ret = -EFAULT;
			else {
				debug("Si47xx_IOC_VOLUME_SET called "
					"vol %d\n", volume);
				ret = (long)Si47xx_dev_volume_set(volume);
				if (ret < 0)
					debug("Si47xx_IOC_VOLUME_SET failed\n");
			}
		}
		break;

	case Si47xx_IOC_VOLUME_GET:
		{
			u8 volume;
			debug("Si47xx_IOC_VOLUME_GET called\n");

			ret = (long)Si47xx_dev_volume_get(&volume);

			if (ret < 0)
				debug("Si47xx_IOC_VOLUME_GET failed\n");
			else if (copy_to_user
				 (argp, (void *)&volume, sizeof(u8)))
				ret = -EFAULT;
		}
		break;

	case Si47xx_IOC_DSMUTE_ON:
		debug("Si47xx_IOC_DSMUTE_ON called\n\n");

		ret = (long)Si47xx_dev_DSMUTE_ON();
		if (ret < 0)
			error("Si47xx_IOC_DSMUTE_ON failed\n");
		break;

	case Si47xx_IOC_DSMUTE_OFF:
		debug("Si47xx_IOC_DSMUTE_OFF called\n\n");

		ret = (long)Si47xx_dev_DSMUTE_OFF();
		if (ret < 0)
			error("Si47xx_IOC_DSMUTE_OFF failed\n");
		break;

	case Si47xx_IOC_MUTE_ON:
		debug("Si47xx_IOC_MUTE_ON called\n");

		ret = (long)Si47xx_dev_MUTE_ON();
		if (ret < 0)
			debug("Si47xx_IOC_MUTE_ON failed\n");
		break;

	case Si47xx_IOC_MUTE_OFF:
		debug("Si47xx_IOC_MUTE_OFF called\n");

		ret = (long)Si47xx_dev_MUTE_OFF();
		if (ret < 0)
			debug("Si47xx_IOC_MUTE_OFF failed\n");
		break;

	case Si47xx_IOC_MONO_SET:
		debug("Si47xx_IOC_MONO_SET called\n");

		ret = (long)Si47xx_dev_MONO_SET();
		if (ret < 0)
			debug("Si47xx_IOC_MONO_SET failed\n");
		break;

	case Si47xx_IOC_STEREO_SET:
		debug("Si47xx_IOC_STEREO_SET called\n");

		ret = (long)Si47xx_dev_STEREO_SET();
		if (ret < 0)
			debug("Si47xx_IOC_STEREO_SET failed\n");
		break;

	case Si47xx_IOC_RSTATE_GET:
		{
			struct dev_state_t dev_state;

			debug("Si47xx_IOC_RSTATE_GET called\n");

			ret = (long)Si47xx_dev_rstate_get(&dev_state);
			if (ret < 0)
				debug("Si47xx_IOC_RSTATE_GET failed\n");
			else if (copy_to_user(argp, (void *)&dev_state,
					      sizeof(dev_state)))
				ret = -EFAULT;
		}
		break;

	case Si47xx_IOC_RDS_DATA_GET:
		{
			struct radio_data_t data;
			debug("Si47xx_IOC_RDS_DATA_GET called\n");

			ret = (long)Si47xx_dev_RDS_data_get(&data);
			if (ret < 0)
				debug(" Si47xx_IOC_RDS_DATA_GET failed\n");
			else if (copy_to_user(argp, (void *)&data,
					      sizeof(data)))
				ret = -EFAULT;
		}
		break;

	case Si47xx_IOC_RDS_ENABLE:
		debug("Si47xx_IOC_RDS_ENABLE called\n");

		ret = (long)Si47xx_dev_RDS_ENABLE();
		if (ret < 0)
			debug("Si47xx_IOC_RDS_ENABLE failed\n");
		break;

	case Si47xx_IOC_RDS_DISABLE:
		debug("Si47xx_IOC_RDS_DISABLE called\n");

		ret = (long)Si47xx_dev_RDS_DISABLE();
		if (ret < 0)
			debug("Si47xx_IOC_RDS_DISABLE failed\n");
		break;

	case Si47xx_IOC_RDS_TIMEOUT_SET:
		{
			u32 time_out;
			debug("Si47xx_IOC_RDS_TIMEOUT_SET called\n");

			if (copy_from_user
			    ((void *)&time_out, argp, sizeof(u32)))
				ret = -EFAULT;
			else {
			ret = (long)Si47xx_dev_RDS_timeout_set(time_out);
				if (ret < 0)
					debug("Si47xx_IOC_RDS_TIMEOUT_SET "
						"failed\n");
			}
		}
		break;

	case Si47xx_IOC_SEEK_CANCEL:
		debug("Si47xx_IOC_SEEK_CANCEL called\n");

		if (Si47xx_dev_wait_flag == SEEK_WAITING) {
			Si47xx_dev_wait_flag = SEEK_CANCEL;
			wake_up_interruptible(&Si47xx_waitq);
		}
		break;

/*VNVS:START 13-OCT'09----
Switch Case statements for calling functions which reads device-id,
chip-id,power configuration, system configuration2 registers */
	case Si47xx_IOC_CHIP_ID_GET:
		{
			struct chip_id chp_id;
			debug("Si47xx_IOC_CHIP_ID called\n");

			ret = (long)Si47xx_dev_chip_id(&chp_id);
			if (ret < 0)
				debug("Si47xx_IOC_CHIP_ID failed\n");
			else if (copy_to_user(argp, (void *)&chp_id,
					      sizeof(chp_id)))
				ret = -EFAULT;
		}
		break;

	case Si47xx_IOC_DEVICE_ID_GET:
		{
			struct device_id dev_id;
			debug("Si47xx_IOC_DEVICE_ID called\n");

			ret = (long)Si47xx_dev_device_id(&dev_id);
			if (ret < 0)
				debug("Si47xx_IOC_DEVICE_ID failed\n");
			else if (copy_to_user(argp, (void *)&dev_id,
					      sizeof(dev_id)))
				ret = -EFAULT;
		}
		break;

	case Si47xx_IOC_SYS_CONFIG2_GET:
		{
			struct sys_config2 sys_conf2;
			debug("Si47xx_IOC_SYS_CONFIG2 called\n");

			ret = (long)Si47xx_dev_sys_config2(&sys_conf2);
			if (ret < 0)
				debug("Si47xx_IOC_SYS_CONFIG2 failed\n");
			else if (copy_to_user(argp, (void *)&sys_conf2,
					      sizeof(sys_conf2)))
				ret = -EFAULT;
		}
		break;

	case Si47xx_IOC_SYS_CONFIG3_GET:
		{
			struct sys_config3 sys_conf3;
			debug("Si47xx_IOC_SYS_CONFIG3 called\n");

			ret = (long)Si47xx_dev_sys_config3(&sys_conf3);
			if (ret < 0)
				debug("Si47xx_IOC_SYS_CONFIG3 failed\n");
			else if (copy_to_user(argp, (void *)&sys_conf3,
					      sizeof(sys_conf3)))
				ret = -EFAULT;
		}
		break;

	case Si47xx_IOC_POWER_CONFIG_GET:
		{
			debug("Si47xx_IOC_POWER_CONFIG called\n");
			ret = -EFAULT;
		}
		break;
/*VNVS:END*/

/*VNVS:START 18-NOV'09*/
		/*Reading AFCRL Bit */
	case Si47xx_IOC_AFCRL_GET:
		{
			u8 afc;
			debug("Si47xx_IOC_AFCRL_GET called\n");

			ret = (long)Si47xx_dev_AFCRL_get(&afc);
			if (ret < 0)
				debug("Si47xx_IOC_AFCRL_GET failed\n");
			else if (copy_to_user(argp, (void *)&afc, sizeof(u8)))
				ret = -EFAULT;
		}
		break;

		/*Setting DE-emphasis Time Constant.
		   For DE=0,TC=50us(Europe,Japan,Australia)
		   and DE=1,TC=75us(USA) */
	case Si47xx_IOC_DE_SET:
		{
			u8 de_tc;
			debug("Si47xx_IOC_DE_SET called\n");

			if (copy_from_user((void *)&de_tc, argp, sizeof(u8)))
				ret = -EFAULT;
			else {
				ret = (long)Si47xx_dev_DE_set(de_tc);
				if (ret < 0)
					debug("Si47xx_IOC_DE_SET failed\n");
			}
		}
		break;

	case Si47xx_IOC_STATUS_RSSI_GET:
		{
			struct status_rssi status;
			debug("Si47xx_IOC_STATUS_RSSI_GET called\n");

			ret = (long)Si47xx_dev_status_rssi(&status);
			if (ret < 0)
				debug("Si47xx_IOC_STATUS_RSSI_GET failed\n");
			else if (copy_to_user(argp, (void *)&status,
					      sizeof(status)))
				ret = -EFAULT;
		}
		break;

	case Si47xx_IOC_SYS_CONFIG2_SET:
		{
			struct sys_config2 sys_conf2;
			unsigned long n;
			debug("Si47xx_IOC_SYS_CONFIG2_SET called\n");

			n = copy_from_user((void *)&sys_conf2, argp,
					   sizeof(sys_conf2));
			if (n) {
				debug("Si47xx_IOC_SYS_CONFIG2_SET() : "
					"copy_from_user() has error!! "
					"Failed to read [%lu] byes!", n);
				ret = -EFAULT;
			} else {
			ret = (long)Si47xx_dev_sys_config2_set(&sys_conf2);
				if (ret < 0)
					debug("Si47xx_IOC_SYS_CONFIG2_SET"
						"failed\n");
			}
		}
		break;

	case Si47xx_IOC_SYS_CONFIG3_SET:
		{
			struct sys_config3 sys_conf3;
			unsigned long n;

			debug("Si47xx_IOC_SYS_CONFIG3_SET called\n");

			n = copy_from_user((void *)&sys_conf3, argp,
					   sizeof(sys_conf3));
			if (n) {
				debug("Si47xx_IOC_SYS_CONFIG3_SET() : "
					"copy_from_user() has error!! "
					"Failed to read [%lu] byes!", n);
				ret = -EFAULT;
			} else {
			ret = (long)Si47xx_dev_sys_config3_set(&sys_conf3);
				if (ret < 0)
					debug("Si47xx_IOC_SYS_CONFIG3_SET "
							"failed\n");
			}
		}
		break;

		/*Resetting the RDS Data Buffer */
	case Si47xx_IOC_RESET_RDS_DATA:
		{
			debug("Si47xx_IOC_RESET_RDS_DATA called\n");

			ret = (long)Si47xx_dev_reset_rds_data();
			if (ret < 0)
				error("Si47xx_IOC_RESET_RDS_DATA failed\n");
		}
		break;
/*VNVS:END*/
	default:
		debug("  ioctl default\n");
		ret = -ENOTTY;
		break;
	}

	debug("Si47xx ioctl done 0x%x", ioctl_cmd);
	return ret;
}
コード例 #2
0
int Si47xx_dev_powerup(void)
{
	int ret = 0;
	u32 value = 100;

	debug("Si47xx_dev_powerup called");

	if (!(RADIO_ON == Si47xx_dev->state.power_state)) {
		ret = powerup();
		if (ret < 0) {
			dev_err(Si47xx_dev->dev, "%s failed %d\n",
				__func__, ret);
		} else if (Si47xx_dev->valid_client_state == eFALSE) {
			dev_err(Si47xx_dev->dev, "Si47xx_dev_powerup called "
					"when DS(state, client) is invalid");
			ret = -1;
		} else {
/* initial settings */
#ifdef CONFIG_RADIO_USE_MI2S
			si47xx_set_property(DIGITAL_OUTPUT_SAMPLE_RATE, 0xBB80);  //44100
			si47xx_set_property(DIGITAL_OUTPUT_FORMAT, 0x0000);   //I2S, 16bit, Riging edge
#endif
#ifdef _ENABLE_RDS_
			si47xx_set_property(FM_RDS_CONFIG, 1);
			si47xx_set_property(GPO_IEN, GPO_IEN_STCIEN_MASK |
				GPO_IEN_STCREP_MASK);
			si47xx_set_property(GPO_IEN, GPO_IEN_STCIEN_MASK |
				GPO_IEN_RDSIEN_MASK | GPO_IEN_STCREP_MASK);
			si47xx_set_property(FM_RDS_INTERRUPT_SOURCE,
				FM_RDS_INTERRUPT_SOURCE_RECV_MASK);
			si47xx_set_property(FM_RDS_CONFIG,
				FM_RDS_CONFIG_RDSEN_MASK |
				(3 << FM_RDS_CONFIG_BLETHA_SHFT) |
				(3 << FM_RDS_CONFIG_BLETHB_SHFT) |
				(3 << FM_RDS_CONFIG_BLETHC_SHFT) |
				(3 << FM_RDS_CONFIG_BLETHD_SHFT));
#endif
/*VNVS:18-NOV'09 : Setting DE-Time Constant as 50us(Europe,Japan,Australia)*/
			si47xx_set_property(FM_DEEMPHASIS, FM_DEEMPH_50US);
			/* SYSCONFIG2_BITSET_SEEKTH( */
			/*      &Si47xx_dev->registers[SYSCONFIG2],2); */
/*VNVS:18-NOV'09 : modified for detecting more stations of good quality*/
			si47xx_set_property(FM_SEEK_TUNE_RSSI_THRESHOLD,
				TUNE_RSSI_THRESHOLD);
			si47xx_set_property(FM_SEEK_BAND_BOTTOM, 8750);
			si47xx_set_property(FM_SEEK_BAND_TOP, 10800);
			Si47xx_dev->settings.band = BAND_87500_108000_kHz;
			Si47xx_dev->settings.bottom_of_band = FREQ_87500_kHz;
			si47xx_set_property(FM_SEEK_FREQ_SPACING,
				CHAN_SPACING_100_kHz);
			Si47xx_dev->settings.channel_spacing =
				CHAN_SPACING_100_kHz;

			/* SYSCONFIG3_BITSET_SKSNR( */
			/*      &Si47xx_dev->registers[SYSCONFIG3],3); */
/*VNVS:18-NOV'09 : modified for detecting more stations of good quality*/
			si47xx_set_property(FM_SEEK_TUNE_SNR_THRESHOLD,
			TUNE_SNR_THRESHOLD);
			Si47xx_dev->settings.timeout_RDS =
				msecs_to_jiffies(value);
			Si47xx_dev->settings.curr_snr = TUNE_SNR_THRESHOLD;
			Si47xx_dev->settings.curr_rssi_th = TUNE_RSSI_THRESHOLD;
			Si47xx_dev->valid = eTRUE;

			Si47xx_dev_STEREO_SET();
#ifdef RDS_INTERRUPT_ON_ALWAYS
/*Initialising read and write indices */
			RDS_Buffer_Index_read = 0;
			RDS_Buffer_Index_write = 0;

			RDS_Data_Available = 0;
			RDS_Data_Lost = 0;
			RDS_Groups_Available_till_now = 0;
#endif

		}
	} else
		debug("Device already Powered-ON");

	ret = request_irq(si47xx_irq, Si47xx_isr,
		IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "Si47xx", NULL);
	si47xx_set_property(0xff00, 0);

	/* tune initial frequency to remove tunestatus func err
	 * sometimes occur tunestatus func err when execute tunestatus function
	 * before to complete tune_freq.
	 * so run tune_freq just after to complete booting sequence*/
	ret = tune_freq(Si47xx_dev->settings.bottom_of_band);

	return ret;
}