Exemplo n.º 1
0
int Si47xx_dev_sys_config2_set(struct sys_config2 *sys_conf2)
{
	int ret = 0;

	debug("Si47xx_dev_sys_config2_set called");

	mutex_lock(&(Si47xx_dev->lock));

	if (Si47xx_dev->valid == eFALSE) {
		dev_err(Si47xx_dev->dev, "Si47xx_dev_sys_config2_set called when DS is invalid");
		ret = -1;
	} else {
		si47xx_set_property(FM_SEEK_TUNE_RSSI_THRESHOLD,
				sys_conf2->rssi_th);
		Si47xx_dev_band_set(sys_conf2->fm_band);
		si47xx_set_property(FM_SEEK_FREQ_SPACING,
			sys_conf2->fm_chan_spac);
		Si47xx_dev->settings.curr_rssi_th = sys_conf2->rssi_th;
		Si47xx_dev->settings.band = sys_conf2->fm_band;
		Si47xx_dev->settings.channel_spacing = sys_conf2->fm_chan_spac;
	}

	mutex_unlock(&(Si47xx_dev->lock));

	return ret;
}
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;
}