예제 #1
0
static int ov5670_flisclk_ctrl(struct v4l2_subdev *sd, int flag)
{
	static const unsigned int clock_khz = 19200;
	struct i2c_client *client = v4l2_get_subdevdata(sd);

	pr_info("%s(), flag = %d\n", __func__, flag);
//SR use osc clock 2,3 as rear/front MCLK, change to default clock 1,2 as rear/front MCLK after SR
	pr_info("HW_ID = %d\n", HW_ID);
	if(HW_ID == 0x3) //SR
	{
		pr_info("SR board \n");
		if (offset_3 == 0) {
#ifdef CONFIG_X86_INTEL_OSC_CLK
			int ret = 0;
			static const unsigned int clock_khz = 19200;
			struct clk *pclk = clk_get(NULL, "osc.3");
			if (pclk == NULL) {
				pr_err("%s: get osc clock failed\n", __func__);
				return -EINVAL;
			}
			clk_prepare(pclk);
			clk_set_rate(pclk, clock_khz);
			if (flag) {
				if (clk_status == 0) {
					ret = clk_enable(pclk);
					clk_status = 1;
					msleep(20);
					pr_info("%s: osc clock 3 enabled\n", __func__);
				}
			} else {
				if (clk_status == 1) {
					clk_disable(pclk);
					clk_status = 0;
					msleep(20);
					pr_info("%s: osc clock 3 disabled\n", __func__);
				}
			}
			clk_put(pclk);
			return ret;
#else
			pr_err("%s: hm2051 clock is not set\n", __func__);
			return 0;
#endif
		} else {
			return intel_scu_ipc_osc_clk(OSC_CLK_CAM1, flag ? clock_khz : 0);
		}
	}
	else{ //ER 
		if (offset_3 == 0) { //as front camera
			pr_info("ER board, 5M as front camera\n");
			return intel_scu_ipc_osc_clk(OSC_CLK_CAM1, flag ? clock_khz : 0);
		}else{ //as rear camera
			pr_info("ER board, 5M as rear camera\n");
			return intel_scu_ipc_osc_clk(OSC_CLK_CAM0, flag ? clock_khz : 0);
		}
	}
}
/*
 * OSC_CLK_AUDIO is connected to the MSIC as well as Audience, so it should be
 * turned on if any one of them requests it to be on and it should be turned off
 * only if no one needs it on.
 */
int intel_scu_ipc_set_osc_clk0(unsigned int enable, enum clk0_mode mode)
{
	int ret = 0, clk_enable;
	static const unsigned int clk_khz = 19200;

	pr_debug("set_clk0 request %s for Mode 0x%x\n",
				enable ? "ON" : "OFF", mode);
	mutex_lock(&osc_clk0_lock);
	if (mode == CLK0_QUERY) {
		ret = osc_clk0_mode;
		goto out;
	}
	if (enable) {
		/* if clock is already on, just add new user */
		if (osc_clk0_mode) {
			osc_clk0_mode |= mode;
			goto out;
		}
		osc_clk0_mode |= mode;
		pr_debug("set_clk0: enabling clk, mode 0x%x\n", osc_clk0_mode);
		clk_enable = 1;
	} else {
		osc_clk0_mode &= ~mode;
		pr_debug("set_clk0: disabling clk, mode 0x%x\n", osc_clk0_mode);
		/* others using the clock, cannot turn it of */
		if (osc_clk0_mode)
			goto out;
		clk_enable = 0;
	}
	pr_debug("configuring OSC_CLK_AUDIO now\n");
	ret = intel_scu_ipc_osc_clk(OSC_CLK_AUDIO, clk_enable ? clk_khz : 0);
out:
	mutex_unlock(&osc_clk0_lock);
	return ret;
}
/*
 * WORKAROUND:
 * This func will return 0 since MCLK is enabled by BIOS
 * and will be always on event if set MCLK failed here.
 * TODO: REMOVE WORKAROUND, err should be returned when
 * set MCLK failed.
 */
static int ov5670_flisclk_ctrl(struct v4l2_subdev *sd, int flag)
{
	static const unsigned int clock_khz = 19200;

#ifdef CONFIG_INTEL_SOC_PMC
	int ret = 0;
	if (flag) {
		ret = pmc_pc_set_freq(OSC_CAM0_CLK, (IS_CHT) ?
				CLK_19P2MHz_XTAL : CLK_19P2MHz);
		if (ret)
			pr_err("ov5670 clock set failed.\n");
	}
	pmc_pc_configure(OSC_CAM0_CLK, flag ? CLK_ON : CLK_OFF);
	return 0;
#elif defined(CONFIG_INTEL_SCU_IPC_UTIL)
	int ret;
    ret = intel_scu_ipc_osc_clk(OSC_CLK_CAM1, flag ? clock_khz : 0);
    msleep(1);
    return ret;

#else
	pr_err("ov5670 clock is not set.\n");
	return 0;
#endif

}
예제 #4
0
static int mt9m114_flisclk_ctrl(struct v4l2_subdev *sd, int flag)
{
	static const unsigned int clock_khz = 19200; //Intel just can support 19.2MHz/9.6MHz/4.8MHz 
	int ret = 0;
	v4l2_err(sd, "%s: ++\n",__func__);
	ret = intel_scu_ipc_osc_clk(OSC_CLK_CAM0, flag ? clock_khz : 0);
	return ret;
}
예제 #5
0
static int t4k35_flisclk_ctrl(struct v4l2_subdev *sd, int flag)
{
	static const unsigned int clock_khz = 19200;
//SR use osc clock 2 as rear MCLK, change to default clock 1 as rear MCLK after SR
	if (HW_ID == 0xFF) {
		HW_ID = Read_HW_ID();
	}
	pr_info("HW_ID = %d\n", HW_ID);
	if(HW_ID == 0x3){ //SR
		pr_info("SR board!!\n");
		return intel_scu_ipc_osc_clk(OSC_CLK_CAM1, flag ? clock_khz : 0);
	}
	else{//ER
		pr_info("ER board!!\n");
		return intel_scu_ipc_osc_clk(OSC_CLK_CAM0, flag ? clock_khz : 0);
	}
}
static int t4k35_180_flisclk_ctrl(struct v4l2_subdev *sd, int flag)
{
	static const unsigned int clock_khz = 19200;
    int ret;
	v4l2_err(sd, "%s: ++\n",__func__);
    ret = intel_scu_ipc_osc_clk(OSC_CLK_CAM0, flag ? clock_khz : 0);
    usleep_range(800, 1000);
	return ret;
}
static int gc2155_flisclk_ctrl(struct v4l2_subdev *sd, int flag)
{
	static const unsigned int clock_khz = 19200;
    int ret = 0;

	pr_info("%s(), flag: %d\n", __func__, flag);
	ret = intel_scu_ipc_osc_clk(OSC_CLK_CAM1, flag ? clock_khz : 0);	
	return ret;
}
static int gc0339_flisclk_ctrl(struct v4l2_subdev *sd, int flag)
{
	static const unsigned int clock_khz = 19200;
	int ret = 0;
	printk("%s: ++\n",__func__);
	ret = intel_scu_ipc_osc_clk(OSC_CLK_CAM1, flag ? clock_khz : 0);
	msleep(5);
	return ret;
}
static int imx135_flisclk_ctrl(struct v4l2_subdev *sd, int flag)
{
	static const unsigned int clock_khz = 19200;
#ifdef CONFIG_INTEL_SCU_IPC_UTIL
	return intel_scu_ipc_osc_clk(OSC_CLK_CAM0, flag ? clock_khz : 0);
#else
	pr_err("imx135 clock is not set.\n");
	return 0;
#endif
}
static int s5k6b2yx_flisclk_ctrl(struct v4l2_subdev *sd, int flag)
{
	static const unsigned int clock_khz = 19200;
	int ret;

	ret = intel_scu_ipc_osc_clk(OSC_CLK_CAM1_SS, flag ? clock_khz : 0);
	if (ret < 0)
		pr_err("%s, camera clock failed, result : %d\n", __func__, ret);

	return ret;
}
static void snd_ctp_complete(struct device *dev)
{
	struct snd_soc_card *card = dev_get_drvdata(dev);
	struct ctp_mc_private *ctx = snd_soc_card_get_drvdata(card);
	pr_debug("In %s\n", __func__);
	/* switch the mclk to the normal mode */
	if (ctx->headset_plug_flag && !ctx->voice_call_flag) {
		if (ctx->ops->mclk_switch) {
			/* recovery the OSC clk to 19.2Mhz when resume */
			intel_scu_ipc_osc_clk(OSC_CLK_AUDIO, 19200);
			ctx->ops->mclk_switch(dev, true);
		}
	}
	snd_soc_resume(dev);
}
static int snd_ctp_prepare(struct device *dev)
{
	struct snd_soc_card *card = dev_get_drvdata(dev);
	struct ctp_mc_private *ctx = snd_soc_card_get_drvdata(card);
	pr_debug("In %s device name\n", __func__);

	/* switch the mclk to the lowpower mode */
	if (ctx->headset_plug_flag && !ctx->voice_call_flag) {
		if (ctx->ops->mclk_switch) {
			ctx->ops->mclk_switch(dev, false);
			/* Decrease the OSC clk to 4.8Mhz when suspend */
			intel_scu_ipc_osc_clk(OSC_CLK_AUDIO, 4800);
		}
	}
	return snd_soc_suspend(dev);
}
static int imx175_flisclk_ctrl(struct v4l2_subdev *sd, int flag)
{
	static const unsigned int clock_khz = 19200;
#ifdef CONFIG_VLV2_PLAT_CLK
	if (flag) {
		int ret;
		ret = vlv2_plat_set_clock_freq(OSC_CAM0_CLK, CLK_19P2MHz);
		if (ret)
			return ret;
	}
	return vlv2_plat_configure_clock(OSC_CAM0_CLK, flag);
#endif
	if (intel_mid_identify_cpu() != INTEL_MID_CPU_CHIP_VALLEYVIEW2)
		return intel_scu_ipc_osc_clk(OSC_CLK_CAM0,
			flag ? clock_khz : 0);
	else
		return 0;
}
static int ov5670_flisclk_ctrl(struct v4l2_subdev *sd, int flag)
{
	static const unsigned int clock_khz = 19200;

#ifdef CONFIG_INTEL_SOC_PMC
	if (flag) {
		int ret;
		ret = pmc_pc_set_freq(OSC_CAM0_CLK, CLK_19P2MHz);
		if (ret)
			return ret;
	}
	return pmc_pc_configure(OSC_CAM0_CLK, flag);
#endif
	if (intel_mid_identify_cpu() != INTEL_MID_CPU_CHIP_VALLEYVIEW2)
		return intel_scu_ipc_osc_clk(OSC_CLK_CAM0,
			flag ? clock_khz : 0);
	else
		return 0;
}
static int imx175_flisclk_ctrl(struct v4l2_subdev *sd, int flag)
{
	static const unsigned int clock_khz = 19200;
#ifdef CONFIG_VLV2_PLAT_CLK
	if (flag) {
		int ret;
		ret = vlv2_plat_set_clock_freq(OSC_CAM0_CLK, CLK_19P2MHz);
		if (ret)
			return ret;
	}
	return vlv2_plat_configure_clock(OSC_CAM0_CLK, flag);
#elif defined(CONFIG_INTEL_SCU_IPC_UTIL)
	return intel_scu_ipc_osc_clk(OSC_CLK_CAM0,
			flag ? clock_khz : 0);
#else
	pr_err("imx175 clock is not set\n");
	return 0;
#endif
}
/*
 * WORKAROUND:
 * This func will return 0 since MCLK is enabled by BIOS
 * and will be always on event if set MCLK failed here.
 * TODO: REMOVE WORKAROUND, err should be returned when
 * set MCLK failed.
 */
static int ov2685f_flisclk_ctrl(struct v4l2_subdev *sd, int flag)
{
	static const unsigned int clock_khz = 19200;
#ifdef CONFIG_VLV2_PLAT_CLK
	int ret = 0;
	if (flag) {
		ret = vlv2_plat_set_clock_freq(OSC_CAM1_CLK, CLK_19P2MHz);
		if (ret)
			pr_err("ov2685f clock set failed.\n");
	}
	vlv2_plat_configure_clock(OSC_CAM1_CLK, flag);
	return 0;
#elif defined(CONFIG_INTEL_SCU_IPC_UTIL)
	return intel_scu_ipc_osc_clk(OSC_CLK_CAM1,
				     flag ? clock_khz : 0);
#else
	pr_err("ov2685f clock is not set.\n");
	return 0;
#endif
}
static int imx134_flisclk_ctrl(struct v4l2_subdev *sd, int flag)
{
#ifdef CONFIG_INTEL_SOC_PMC
	if (flag) {
		int ret;
		ret = pmc_pc_set_freq(OSC_CAM0_CLK, CLK_19P2MHz);
		if (ret)
			return ret;
		return pmc_pc_configure(OSC_CAM0_CLK, CLK_ON);
	}
	return pmc_pc_configure(OSC_CAM0_CLK, CLK_OFF);
#elif defined(CONFIG_INTEL_SCU_IPC_UTIL)
	static const unsigned int clock_khz = 19200;
	return intel_scu_ipc_osc_clk(OSC_CLK_CAM0,
			flag ? clock_khz : 0);
#else
	pr_err("imx134 clock is not set.\n");
	return 0;
#endif
}
static int m10mo_flisclk_ctrl(struct v4l2_subdev *sd, int flag)
{
#ifdef CONFIG_INTEL_SOC_PMC
	int ret;
	if (flag) {
		ret = pmc_pc_set_freq(OSC_CAM_CLK, (IS_CHT) ?
			CLK_19P2MHz_XTAL : CLK_19P2MHz);
		if (ret)
			return ret;
		ret = pmc_pc_configure(OSC_CAM_CLK, 1);
	} else {
		ret = pmc_pc_configure(OSC_CAM_CLK, 2);
	}
	pr_info("M10MO clock control. flag=%d ret=%d\n", flag, ret);
	return ret;
#elif defined(CONFIG_INTEL_SCU_IPC_UTIL)
	static const unsigned int clock_khz = 19200;
	return intel_scu_ipc_osc_clk(OSC_CLK_CAM0, flag ? clock_khz : 0);
#else
	pr_err("clock is not set.\n");
	return 0;
#endif
}
static int ov8865_flisclk_ctrl(struct v4l2_subdev *sd, int flag)
{
	static const unsigned int clock_khz = 19200;
	OV8865_PLAT_LOG(1,"%s %d flag:%d\n", __func__, __LINE__, flag);
	ov8865_verify_gpio_power();
#ifdef CONFIG_VLV2_PLAT_CLK
	if (flag) {
		int ret;
		ret = vlv2_plat_set_clock_freq(OSC_CAM0_CLK, CLK_19P2MHz);
		if (ret)
			return ret;
	}
	usleep_range(2000, 2500);
	OV8865_PLAT_LOG(1,"%s %d VLV2 PLAT sleep 2ms for clock to stable\n", __func__, __LINE__);
	return vlv2_plat_configure_clock(OSC_CAM0_CLK, flag);
#elif defined(CONFIG_INTEL_SCU_IPC_UTIL)
	return intel_scu_ipc_osc_clk(OSC_CLK_CAM0,
			flag ? clock_khz : 0);
#else
	pr_err("ov8865 clock is not set.\n");
	return 0;
#endif
}
static int hm2056_flisclk_ctrl(struct v4l2_subdev *sd, int flag)
{
	static const unsigned int clock_khz = 19200;
    v4l2_err(sd, "%s: ++\n",__func__);
	return intel_scu_ipc_osc_clk(OSC_CLK_CAM1, flag ? clock_khz : 0);
}
static int mt9v113_flisclk_ctrl(struct v4l2_subdev *sd, int flag)
{
	static const unsigned int clock_khz = 19200;
	return intel_scu_ipc_osc_clk(OSC_CLK_CAM1, flag ? clock_khz : 0);
}
/**
 *	scu_ipc_ioctl		-	control ioctls for the SCU
 *	@fp: file handle of the SCU device
 *	@cmd: ioctl coce
 *	@arg: pointer to user passed structure
 *
 *	Support the I/O and firmware flashing interfaces of the SCU
 */
static long scu_ipc_ioctl(struct file *fp, unsigned int cmd,
							unsigned long arg)
{
	int ret = -EINVAL;
	struct scu_ipc_data  data;
	void __user *argp = (void __user *)arg;
	int platform;

	/* Only IOCTL cmd allowed to pass through without capability check */
	/* is getting fw version info, all others need to check to prevent */
	/* arbitrary access to all sort of bit of the hardware exposed here*/

	if (cmd != INTEL_SCU_IPC_FW_REVISION_GET && !capable(CAP_SYS_RAWIO))
		return -EPERM;

	platform = intel_mid_identify_cpu();
	switch (cmd) {
	case INTEL_SCU_IPC_READ_FBMODE_FROM_OSNIB:
	{
		u8 fb_mode;
		ret = intel_scu_ipc_read_osnib_fb_mode(&fb_mode);
		if (ret < 0) {
			pr_err("read fb_mode from ipc failed!!\n");
			return ret;
		}
		ret = copy_to_user(argp, &fb_mode, 1);
		break;
	}
	case INTEL_SCU_IPC_WRITE_FBMODE_TO_OSNIB:
	{
		u8 fb_mode;

		ret = copy_from_user(&fb_mode, (u8 *)arg, 1);
		if (ret < 0) {
			pr_err("copy fb_mode from user failed!!\n");
			return ret;
		}
		ret = intel_scu_ipc_write_osnib_fb_mode(fb_mode);
		break;
	}
	case INTEL_SCU_IPC_READ_BOS_FROM_OSNIB:
	{
		u8 resync_reason;
		ret = intel_scu_ipc_read_osnib_bos(&resync_reason);
		if (ret < 0)
			return ret;
		ret = copy_to_user(argp, &resync_reason, 1);
		break;
	}
	case INTEL_SCU_IPC_WRITE_BOS_TO_OSNIB:
	{
		u8 data;

		ret = copy_from_user(&data, (u8 *)arg, 1);
		if (ret < 0) {
			pr_err("copy from user failed!!\n");
			return ret;
		}
		ret = intel_scu_ipc_write_osnib_bos(data);
		break;
	}
	case INTEL_SCU_IPC_READ_RR_FROM_OSNIB:
	{
		u8 reboot_reason;
		ret = intel_scu_ipc_read_osnib_rr(&reboot_reason);
		if (ret < 0)
			return ret;
		ret = copy_to_user(argp, &reboot_reason, 1);
		break;
	}
	case INTEL_SCU_IPC_WRITE_RR_TO_OSNIB:
	{
		u8 data;

		ret = copy_from_user(&data, (u8 *)arg, 1);
		if (ret < 0) {
			pr_err("copy from user failed!!\n");
			return ret;
		}
		ret = intel_scu_ipc_write_osnib_rr(data);
		break;
	}
	case INTEL_SCU_IPC_WRITE_ALARM_FLAG_TO_OSNIB:
	{
		u8 flag, data;
		ret = copy_from_user(&flag, (u8 *)arg, 1);
		if (ret < 0) {
			pr_err("copy from user failed!!\n");
			return ret;
		}
		ret = intel_scu_ipc_read_osnib(&data, 1, OSNIB_ALARM_OFFSET);
		if (ret < 0)
			return ret;
		if (flag)
			data = data | 0x1; /* set alarm flag */
		else
			data = data & 0xFE; /* clear alarm flag */
		ret = intel_scu_ipc_write_osnib(&data, 1, OSNIB_ALARM_OFFSET);
		break;
	}
	case INTEL_SCU_IPC_READ_VBATTCRIT:
	{
		u32 value;

		pr_debug("cmd = INTEL_SCU_IPC_READ_VBATTCRIT");
		ret = intel_scu_ipc_read_mip((u8 *)&value, 4, 0x318, 1);
		if (ret < 0)
			return ret;
		pr_debug("VBATTCRIT VALUE = %x\n", value);
		ret = copy_to_user(argp, &value, 4);
		break;
	}
	case INTEL_SCU_IPC_FW_REVISION_GET:
	{
		struct scu_ipc_version version;

		if (copy_from_user(&version, argp, sizeof(u32)))
			return -EFAULT;

		if (version.count > 16)
			return -EINVAL;

		ret = intel_scu_ipc_command(IPCMSG_FW_REVISION, 0,
					NULL, 0, (u32 *)version.data, 4);
		if (ret < 0)
			return ret;

		if (copy_to_user(argp + sizeof(u32),
					version.data, version.count))
			ret = -EFAULT;
		break;
	}
	case INTEL_SCU_IPC_OSC_CLK_CNTL:
	{
		struct osc_clk_t osc_clk;

		if (copy_from_user(&osc_clk, argp, sizeof(struct osc_clk_t)))
			return -EFAULT;

		ret = intel_scu_ipc_osc_clk(osc_clk.id, osc_clk.khz);
		if (ret)
			pr_err("%s: failed to set osc clk\n", __func__);

		break;
	}
	case INTEL_SCU_IPC_READ_BYTE_IN_OSNIB:
	{
		struct osnib_data read_data;

		ret = copy_from_user(&read_data, (u8 *)arg,
					sizeof(struct scu_ipc_data));
		if (ret < 0) {
			pr_err("copy from user failed!!\n");
			return ret;
		}
		if ((read_data.offset-OSNIB_OFFSET) >= 32)
			return -EINVAL;
		ret = intel_scu_ipc_read_osnib_byte(read_data.offset,
							&read_data.data);
		if (ret < 0)
			return ret;
		ret = copy_to_user(argp, &read_data,
					sizeof(struct scu_ipc_data));
		break;
	}
	case INTEL_SCU_IPC_WRITE_BYTE_IN_OSNIB:
	{
		struct osnib_data write_data;

		ret = copy_from_user(&write_data, (u8 *)arg,
					sizeof(struct scu_ipc_data));
		if (ret < 0) {
			pr_err("copy from user failed!!\n");
			return ret;
		}
		if ((write_data.offset-OSNIB_OFFSET) >= 32)
			return -EINVAL;
		ret = intel_scu_ipc_write_osnib_byte(write_data.offset,
							write_data.data);
		if (ret < 0)
			return ret;
		break;
	}
	default:
		if (copy_from_user(&data, argp, sizeof(struct scu_ipc_data)))
			return -EFAULT;
		ret = scu_reg_access(cmd, &data);
		if (ret < 0)
			return ret;
		if (copy_to_user(argp, &data, sizeof(struct scu_ipc_data)))
			return -EFAULT;
		return 0;
	}

	return ret;
}