static int sharp5_cmd_panel_reset(struct mdfld_dsi_config *dsi_config)
{
	int ret = 0;
	u8 *vaddr = NULL, *vaddr1 = NULL;
	int reg_value_scl = 0;

	PSB_DEBUG_ENTRY("\n");

	/* Because when reset touchscreen panel, touchscreen will pull i2c bus
	 * to low, sometime this operation will cause i2c bus enter into wrong
	 * status, so before reset, switch i2c scl pin */
	vaddr1 = ioremap(SECURE_I2C_FLIS_REG, 4);
	reg_value_scl = ioread32(vaddr1);
	reg_value_scl &= ~0x1000;
	rpmsg_send_generic_raw_command(RP_INDIRECT_WRITE, 0,
					(u8 *)&reg_value_scl, 4,
					NULL, 0,
					SECURE_I2C_FLIS_REG, 0);

	intel_scu_ipc_msic_vprog2(true);
	usleep_range(2000, 2500);

	if (bias_en_gpio == 0) {
		bias_en_gpio = 189;
		ret = gpio_request(bias_en_gpio, "bias_enable");
		if (ret) {
			DRM_ERROR("Faild to request bias_enable gpio\n");
			return -EINVAL;
		}
		gpio_direction_output(bias_en_gpio, 0);
	}

	_get_panel_reset_gpio();

	gpio_direction_output(bias_en_gpio, 0);
	gpio_direction_output(mipi_reset_gpio, 0);
	gpio_set_value_cansleep(bias_en_gpio, 0);
	gpio_set_value_cansleep(mipi_reset_gpio, 0);
	usleep_range(2000, 2500);
	gpio_set_value_cansleep(bias_en_gpio, 1);
	usleep_range(2000, 2500);
	gpio_set_value_cansleep(mipi_reset_gpio, 1);
	usleep_range(3000, 3500);
	vaddr = ioremap(0xff0c2d00, 0x60);
	iowrite32(0x3221, vaddr + 0x1c);
	usleep_range(2000, 2500);
	iounmap(vaddr);

	/* switch i2c scl pin back */
	reg_value_scl |= 0x1000;
	rpmsg_send_generic_raw_command(RP_INDIRECT_WRITE, 0,
					(u8 *)&reg_value_scl, 4,
					NULL, 0,
					SECURE_I2C_FLIS_REG, 0);
	iounmap(vaddr1);
	return 0;
}
int camera_set_vprog_power(enum camera_vprog vprog, bool flag,
			   enum camera_vprog_voltage voltage)
{
	static struct vprog_status status[CAMERA_VPROG_NUM];
	static DEFINE_MUTEX(mutex_power);
	int ret = 0;

	if (vprog >= CAMERA_VPROG_NUM) {
		pr_err("%s: invalid vprog number: %d\n", __func__, vprog);
		return -EINVAL;
	}

	mutex_lock(&mutex_power);
	/*
	 * only set power at: first to power on last to power off
	 */
	if ((flag && status[vprog].user == 0)
	    || (!flag && status[vprog].user == 1)) {
		switch (vprog) {
		case CAMERA_VPROG1:
			if (voltage == DEFAULT_VOLTAGE) {
				ret = intel_scu_ipc_msic_vprog1(flag);
			} else {
				pr_err("Error: non-default vprog1 voltage\n");
				ret = -EINVAL;
			}
			break;
		case CAMERA_VPROG2:
			if (voltage == DEFAULT_VOLTAGE) {
				ret = intel_scu_ipc_msic_vprog2(flag);
			} else {
				pr_err("Error: non-default vprog2 voltage\n");
				ret = -EINVAL;
			}
			break;
		case CAMERA_VPROG3:
			ret = camera_set_vprog3(flag, voltage);
			break;
		default:
			pr_err("camera set vprog power: invalid pin number.\n");
			ret = -EINVAL;
		}
		if (ret)
			goto done;
	}

	if (flag)
		status[vprog].user++;
	else
		if (status[vprog].user)
			status[vprog].user--;
done:
	mutex_unlock(&mutex_power);
	return ret;
}
Exemplo n.º 3
0
int do_setup_ddr(struct device *dev)
{
	struct psh_ia_priv *ia_data =
			(struct psh_ia_priv *)dev_get_drvdata(dev);
	struct psh_plt_priv *plt_priv =
			(struct psh_plt_priv *)ia_data->platform_priv;
	uintptr_t ddr_phy = plt_priv->ddr_phy;
	uintptr_t imr2_phy = plt_priv->imr2_phy;
	const struct firmware *fw_entry;
	struct ia_cmd cmd_user = {
		.cmd_id = CMD_SETUP_DDR,
		.sensor_id = 0,
		};
	static int fw_load_done;
	int load_default = 0;
	char fname[40];

	if (fw_load_done)
		return 0;

#ifdef VPROG2_SENSOR
	intel_scu_ipc_msic_vprog2(1);
	msleep(500);
#endif
again:
	if (!request_firmware(&fw_entry, fname, dev)) {
		if (!fw_entry)
			return -ENOMEM;

		psh_debug("psh fw size %d virt:0x%p\n",
				(int)fw_entry->size, fw_entry->data);
		if (fw_entry->size > APP_IMR_SIZE) {
			psh_err("psh fw size too big\n");
		} else {
			struct ia_cmd cmd = {
				.cmd_id = CMD_RESET,
				.sensor_id = 0,
				};

			memcpy(plt_priv->imr2, fw_entry->data,
				fw_entry->size);
			*(uintptr_t *)(&cmd.param) = imr2_phy;
			cmd.tran_id = 0x1;
			if (process_send_cmd(ia_data, PSH2IA_CHANNEL3, &cmd, 7))
				return -1;
			ia_data->load_in_progress = 1;
			wait_for_completion_timeout(&ia_data->cmd_load_comp,
					3 * HZ);
			fw_load_done = 1;
		}
		release_firmware(fw_entry);
	} else {
		psh_err("cannot find psh firmware(%s)\n", fname);
		if (!load_default) {
			psh_err("try to load default psh.bin\n");
			snprintf(fname, 20, "psh.bin");
			load_default = 1;
			goto again;
		}
	}
	ia_lbuf_read_reset(ia_data->lbuf);
	*(unsigned long *)(&cmd_user.param) = ddr_phy;
	return ia_send_cmd(ia_data, &cmd_user, 7);
}

static void psh2ia_channel_handle(u32 msg, u32 param, void *data)
{
	struct pci_dev *pdev = (struct pci_dev *)data;
	struct psh_ia_priv *ia_data =
			(struct psh_ia_priv *)dev_get_drvdata(&pdev->dev);
	struct psh_plt_priv *plt_priv =
			(struct psh_plt_priv *)ia_data->platform_priv;
	u8 *dbuf = NULL;
	u16 size = 0;

	if (unlikely(ia_data->load_in_progress)) {
		ia_data->load_in_progress = 0;
		complete(&ia_data->cmd_load_comp);
		return;
	}

	while (!ia_lbuf_read_next(ia_data,
			&plt_priv->lbuf, &dbuf, &size)) {
		ia_handle_frame(ia_data, dbuf, size);
	}
	sysfs_notify(&pdev->dev.kobj, NULL, "data_size");
}

static int psh_imr_init(struct pci_dev *pdev,
			int imr_src, uintptr_t *phy_addr, void **virt_addr,
			unsigned size, int bar)
{
	struct page *pg;
	void __iomem *mem;
	int ret = 0;
	unsigned long start = 0, len;

	if (imr_src == imr_allocate) {
		/* dynamic alloct memory region */
		pg = alloc_pages(GFP_KERNEL | GFP_DMA32 | __GFP_ZERO,
						get_order(size));
		if (!pg) {
			dev_err(&pdev->dev, "can not allocate app page imr buffer\n");
			ret = -ENOMEM;
			goto err;
		}
		*phy_addr = page_to_phys(pg);
		*virt_addr = page_address(pg);
	} else if (imr_src == imr_pci_shim) {
		/* dedicate isolated memory region */
		start = pci_resource_start(pdev, bar);
		len = pci_resource_len(pdev, bar);
		if (!start || !len) {
			dev_err(&pdev->dev, "bar %d address not set\n", bar);
			ret = -EINVAL;
			goto err;
		}

		ret = pci_request_region(pdev, bar, "psh");
		if (ret) {
			dev_err(&pdev->dev, "failed to request psh region "
				"0x%lx-0x%lx\n", start,
				(unsigned long)pci_resource_end(pdev, bar));
			goto err;
		}

		mem = ioremap_nocache(start, len);
		if (!mem) {
			dev_err(&pdev->dev, "can not ioremap app imr address\n");
			ret = -EINVAL;
			goto err_ioremap;
		}

		*phy_addr = start;
		*virt_addr = (void *)mem;
	} else {
		dev_err(&pdev->dev, "Invalid chip imr source\n");
		ret = -EINVAL;
		goto err;
	}

	return 0;

err_ioremap:
	pci_release_region(pdev, bar);
err:
	return ret;
}

static void psh_imr_free(int imr_src, void *virt_addr, unsigned size)
{
	if (imr_src == imr_allocate)
		__free_pages(virt_to_page(virt_addr), get_order(size));
	else if (imr_src == imr_pci_shim)
		iounmap((void __iomem *)virt_addr);
}

static int psh_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
	int ret = -1;
	struct psh_ia_priv *ia_data;
	struct psh_plt_priv *plt_priv;

	ret = pci_enable_device(pdev);
	if (ret) {
		dev_err(&pdev->dev, "fail to enable psh pci device\n");
		goto pci_err;
	}

	plt_priv = kzalloc(sizeof(*plt_priv), GFP_KERNEL);
	if (!plt_priv) {
		dev_err(&pdev->dev, "can not allocate plt_priv\n");
		goto plt_err;
	}

	switch (intel_mid_identify_cpu()) {
	case INTEL_MID_CPU_CHIP_TANGIER:
		if (intel_mid_soc_stepping() == 0)
			plt_priv->imr_src = imr_allocate;
		else
			plt_priv->imr_src = imr_pci_shim;
		break;
	case INTEL_MID_CPU_CHIP_ANNIEDALE:
		plt_priv->imr_src = imr_pci_shim;
		break;
	default:
		dev_err(&pdev->dev, "error memory region\n");
		goto psh_imr2_err;
		break;
	}

	/* init IMR2 */
	ret = psh_imr_init(pdev, plt_priv->imr_src,
				&plt_priv->imr2_phy, &plt_priv->imr2,
				APP_IMR_SIZE, 0);
	if (ret)
		goto psh_imr2_err;


	/* init IMR3 */
	ret = psh_imr_init(pdev, plt_priv->imr_src,
				&plt_priv->ddr_phy, &plt_priv->ddr,
				BUF_IA_DDR_SIZE, 1);
	if (ret)
		goto psh_ddr_err;

	ret = psh_ia_common_init(&pdev->dev, &ia_data);
	if (ret) {
		dev_err(&pdev->dev, "fail to init psh_ia_common\n");
		goto psh_ia_err;
	}

	ia_lbuf_read_init(&plt_priv->lbuf,
				plt_priv->ddr,
				BUF_IA_DDR_SIZE, NULL);
	ia_data->lbuf = &plt_priv->lbuf;

	plt_priv->hwmon_dev = hwmon_device_register(&pdev->dev);
	if (!plt_priv->hwmon_dev) {
		dev_err(&pdev->dev, "fail to register hwmon device\n");
		goto hwmon_err;
	}

	ia_data->platform_priv = plt_priv;

	ret = intel_psh_ipc_bind(PSH_RECV_CH0, psh2ia_channel_handle, pdev);
	if (ret) {
		dev_err(&pdev->dev, "fail to bind channel\n");
		goto irq_err;
	}

	/* just put this dev into suspend status always, since this is fake */
	pm_runtime_put_noidle(&pdev->dev);
	pm_runtime_allow(&pdev->dev);
	return 0;

irq_err:
	hwmon_device_unregister(plt_priv->hwmon_dev);
hwmon_err:
	psh_ia_common_deinit(&pdev->dev);
psh_ia_err:
	psh_imr_free(plt_priv->imr_src, plt_priv->ddr, BUF_IA_DDR_SIZE);
psh_ddr_err:
	psh_imr_free(plt_priv->imr_src, plt_priv->imr2, APP_IMR_SIZE);
psh_imr2_err:
	kfree(plt_priv);
plt_err:
	pci_dev_put(pdev);
pci_err:
	return ret;
}
static int mdfld_dsi_jdi_panel_reset(struct mdfld_dsi_config *dsi_config)
{
	u8 *vaddr1 = NULL;
	int reg_value_scl = 0;
	int ret = 0;

	PSB_DEBUG_ENTRY("\n");

	/* Because when reset touchscreen panel, touchscreen will pull i2c bus
	 * to low, sometime this operation will cause i2c bus enter into wrong
	 * status, so before reset, switch i2c scl pin */
	vaddr1 = ioremap(SECURE_I2C_FLIS_REG, 4);
	reg_value_scl = ioread32(vaddr1);
	reg_value_scl &= ~0x1000;
	rpmsg_send_generic_raw_command(RP_INDIRECT_WRITE, 0,
					(u8 *)&reg_value_scl, 4,
					NULL, 0,
					SECURE_I2C_FLIS_REG, 0);

	intel_scu_ipc_msic_vprog2(true);

	/* For meeting tRW1 panel spec */
	usleep_range(2000, 2500);

	if (bias_en_gpio == 0) {
		bias_en_gpio = 189;
		ret = gpio_request(bias_en_gpio, "bias_enable");
		if (ret) {
			DRM_ERROR("Faild to request bias_enable gpio\n");
			return -EINVAL;
		}
		gpio_direction_output(bias_en_gpio, 0);
	}
	if (mipi_reset_gpio == 0) {
		ret = get_gpio_by_name("disp0_rst");
		if (ret < 0) {
			DRM_ERROR("Faild to get panel reset gpio, " \
				  "use default reset pin\n");
			return -EINVAL;
		}
		mipi_reset_gpio = ret;
		ret = gpio_request(mipi_reset_gpio, "mipi_display");
		if (ret) {
			DRM_ERROR("Faild to request panel reset gpio\n");
			return -EINVAL;
		}
		gpio_direction_output(mipi_reset_gpio, 0);
	}
	gpio_direction_output(bias_en_gpio, 0);
	gpio_direction_output(mipi_reset_gpio, 0);
	gpio_set_value_cansleep(bias_en_gpio, 0);
	gpio_set_value_cansleep(mipi_reset_gpio, 0);
	usleep_range(2000, 2500);
	gpio_set_value_cansleep(bias_en_gpio, 1);
	usleep_range(2000, 2500);
	gpio_set_value_cansleep(mipi_reset_gpio, 1);
	usleep_range(2000, 2500);
	/* switch i2c scl pin back */
	reg_value_scl |= 0x1000;
	rpmsg_send_generic_raw_command(RP_INDIRECT_WRITE, 0,
					(u8 *)&reg_value_scl, 4,
					NULL, 0,
					SECURE_I2C_FLIS_REG, 0);
	iounmap(vaddr1);

	return 0;
}
Exemplo n.º 5
0
/*
 * Checking the SOC type is temporary workaround to enable OV5670
 * on Bodegabay (tangier) platform. Once standard regulator devices
 * (e.g. vprog2, vprog1) and control functions (pmic_avp) are added
 * for the platforms with tangier, then we can revert this change.
 * ([email protected])
 */
static int ov5670_power_ctrl(struct v4l2_subdev *sd, int flag)
{
	struct i2c_client *client = v4l2_get_subdevdata(sd);
	int ret = 0, gpio;

	if (offset_3 != 0) {
		if (camera_2v8_vcm_power_enable < 0) {
		
			gpio = camera_sensor_gpio(-1, "NFC-intr",
					GPIOF_DIR_OUT, 0);
			if (gpio < 0)
				return gpio;
		
			camera_2v8_vcm_power_enable = gpio;/*174*/
			/* set camera vcm power pin mode to gpio */
			lnw_gpio_set_alt(camera_2v8_vcm_power_enable, LNW_GPIO);
			pr_err("%s: set 2.8V vcm as GPIO\n", __func__);
		}
	}
	
	if (camera_1v2_power_enable < 0) {
		gpio = camera_sensor_gpio(-1, "GP_CAMERA_2_PD",
				GPIOF_DIR_OUT, 0);
		if (gpio < 0)
			return gpio;
		camera_1v2_power_enable = gpio;
		/* set camera vcm power pin mode to gpio */
		lnw_gpio_set_alt(camera_1v2_power_enable, LNW_GPIO);
		pr_err("%s: Set 1.2V as GPIO\n", __func__);
	}

	if (flag) {
		if (offset_3 == 0) {
			if (camera_reset < 0) {
		
				ret = camera_sensor_gpio(-1, "GP_SUB_CAM_PWDN",
							GPIOF_DIR_OUT, 0);
				printk("%s: request gpio camera_reset = %d, flag = %d\n", __func__, ret, flag);
				if (ret < 0)
					return ret;
		
				camera_reset = ret;/*48*/
				printk("%s: 8M sku offset_3 = %d\n", __func__, offset_3);
			}
		} else {
			if (camera_reset < 0) {
				ret = camera_sensor_gpio(-1, GP_CAMERA_0_RESET,
							GPIOF_DIR_OUT, 0);
				printk("%s: request gpio camera_reset = %d, flag = %d\n", __func__, ret, flag);
				if (ret < 0)
					return ret;
				camera_reset = ret; /*9*/
				printk("%s: 5M sku offset_3 = %d\n", __func__, offset_3);
			}
		}

		if (camera_reset >= 0){
			gpio_set_value(camera_reset, 0);
			printk("%s: camera_reset = 0\n", __func__);
			msleep(1);
		}
	}

	if (flag) {
		ret = intel_scu_ipc_msic_vprog1(flag);	//2.8V
		if (ret) {
			pr_err("%s: 2.8V power failed\n", __func__);
			return ret;
		}

		ret = intel_scu_ipc_msic_vprog2(flag);	//1.8V
		if (ret) {
			pr_err("%s: 1.8V power failed\n", __func__);
			return ret;
		}

		if (offset_3 != 0) {
			ret = control_vcm_phy_power(PMIC_VLDOCNT, flag);
			pr_err("%s: Set camera vcm 2.8V(V_SWITCH) on\n", __func__);
			if (ret) {
				pr_err("%s: VCM 3.3V power failed\n", __func__);
				return ret;
			}
		}

		if (offset_3 != 0) {
			pr_err("%s: Set camera vcm 2.8V on = %d\n", __func__, camera_2v8_vcm_power_enable);
			gpio_set_value(camera_2v8_vcm_power_enable, 1);
		}
		pr_err("%s: Set camera 1.2V on = %d\n", __func__, camera_1v2_power_enable);
		gpio_set_value(camera_1v2_power_enable, 1);
	}else {
		pr_err("%s: Set camera 1.2V off\n", __func__);
		gpio_set_value(camera_1v2_power_enable, 0);
		gpio_free(camera_1v2_power_enable);
		camera_1v2_power_enable = -1;
		if (offset_3 != 0) {
			pr_err("%s: Set camera vcm 2.8V off\n", __func__);
			gpio_set_value(camera_2v8_vcm_power_enable, 0);
			gpio_free(camera_2v8_vcm_power_enable);
			camera_2v8_vcm_power_enable = -1;
		}

		if (offset_3 != 0) {
			ret = control_vcm_phy_power(PMIC_VLDOCNT, flag);
			pr_err("%s: Set camera vcm 2.8V(V_SWITCH) off\n", __func__);
			if (ret) {
				pr_err("%s: VCM 3.3V power failed\n", __func__);
				return ret;
			}
		}
		
		ret = intel_scu_ipc_msic_vprog2(flag);	//1.8V
		if (ret) {
			pr_err("%s: 1.8V power failed\n", __func__);
			return ret;
		}
		
		ret = intel_scu_ipc_msic_vprog1(flag);	//2.8V
		if (ret) {
			pr_err("%s: 2.8V power failed\n", __func__);
			return ret;
		}
	}
	
	if (flag)
		usleep_range(1000, 1200);

	return ret;
}