Beispiel #1
0
static int pn547_probe(struct i2c_client *client,
		       const struct i2c_device_id *id)
{
	int ret;
	int err;
	struct pn547_i2c_platform_data *platform_data;
	struct pn547_dev *pn547_dev;
	struct pinctrl *nfc_pinctrl;
	struct pinctrl_state *nfc_suspend;
	struct pinctrl_state *nfc_active;
	//nfc_power_onoff(1);
	//msleep(20);

	if (client->dev.of_node) {
		platform_data = devm_kzalloc(&client->dev,
			sizeof(struct pn547_i2c_platform_data), GFP_KERNEL);
		if (!platform_data) {
			dev_err(&client->dev, "Failed to allocate memory\n");
			return -ENOMEM;
		}
		err = pn547_parse_dt(&client->dev, platform_data);
		if (err)
			return err;
	} else {
		platform_data = client->dev.platform_data;
	}

	if (platform_data == NULL) {
		pr_err("%s : nfc probe fail\n", __func__);
		return -ENODEV;
	}

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		pr_err("%s : need I2C_FUNC_I2C\n", __func__);
		return -ENODEV;
	}

	ret = gpio_request(platform_data->irq_gpio, "nfc_int");
	if (ret)
		return -ENODEV;
	ret = gpio_request(platform_data->ven_gpio, "nfc_ven");
	if (ret)
		goto err_ven;
	ret = gpio_request(platform_data->firm_gpio, "nfc_firm");
	if (ret)
		goto err_firm;

	/* Get pinctrl if target uses pinctrl */
	nfc_pinctrl = devm_pinctrl_get(&client->dev);
	if (IS_ERR(nfc_pinctrl)) {
		pr_debug("Target does not use pinctrl\n");
		nfc_pinctrl = NULL;
	} else {
		nfc_suspend = pinctrl_lookup_state(nfc_pinctrl, "nfc_suspend");
		nfc_active = pinctrl_lookup_state(nfc_pinctrl, "nfc_active");
		if (IS_ERR(nfc_suspend)) {
			pr_info("%s fail to suspend lookup_state\n", __func__);
			goto err_exit;
		}
		if (IS_ERR(nfc_active)) {
			pr_info("%s fail to active lookup_state\n", __func__);
			goto err_exit;
		}
		ret = pinctrl_select_state(nfc_pinctrl, nfc_suspend);
		if (ret != 0) {
			pr_err("%s: fail to select_state suspend\n", __func__);
			goto err_exit;
		}
		ret = pinctrl_select_state(nfc_pinctrl, nfc_active);
		if (ret != 0) {
			pr_err("%s: fail to select_state active\n", __func__);
			goto err_exit;
		}
		devm_pinctrl_put(nfc_pinctrl);
	}

	pn547_dev = kzalloc(sizeof(*pn547_dev), GFP_KERNEL);
	if (pn547_dev == NULL) {
		dev_err(&client->dev,
			"failed to allocate memory for module data\n");
		ret = -ENOMEM;
		goto err_exit;
	}

	pr_info("%s : IRQ num %d\n", __func__, client->irq);

	pn547_dev->irq_gpio = platform_data->irq_gpio;
	pn547_dev->ven_gpio = platform_data->ven_gpio;
	pn547_dev->firm_gpio = platform_data->firm_gpio;
	pn547_dev->conf_gpio = platform_data->conf_gpio;
	pn547_dev->nfc_clock = platform_data->nfc_clock;

	pn547_dev->client = client;
#ifdef CONFIG_NFC_PN547_8916_CLK_CTL
	pn547_dev->nfc_enable = 0;
#endif
	/* init mutex and queues */
	init_waitqueue_head(&pn547_dev->read_wq);
	mutex_init(&pn547_dev->read_mutex);

	pn547_dev->pn547_device.minor = MISC_DYNAMIC_MINOR;
#ifdef CONFIG_NFC_PN547
	pn547_dev->pn547_device.name = "pn547";
#else
	pn547_dev->pn547_device.name = "pn544";
#endif
	pn547_dev->pn547_device.fops = &pn547_dev_fops;

	ret = misc_register(&pn547_dev->pn547_device);
	if (ret) {
		pr_err("%s : misc_register failed\n", __FILE__);
		goto err_misc_register;
	}

	/* request irq.  the irq is set whenever the chip has data available
	 * for reading.  it is cleared when all data has been read.
	 */
	pr_info("%s : requesting IRQ %d\n", __func__, client->irq);
	gpio_direction_input(pn547_dev->irq_gpio);
	gpio_direction_output(pn547_dev->ven_gpio, 0);
	gpio_direction_output(pn547_dev->firm_gpio, 0);

	i2c_set_clientdata(client, pn547_dev);
	wake_lock_init(&pn547_dev->nfc_wake_lock,
			WAKE_LOCK_SUSPEND, "nfc_wake_lock");

#if 0
	nfc_power_onoff(pn547_dev,1);
#endif

	ret = request_irq(client->irq, pn547_dev_irq_handler,
			  IRQF_TRIGGER_RISING, "pn547", pn547_dev);
	if (ret) {
		dev_err(&client->dev, "request_irq failed\n");
		goto err_request_irq_failed;
	}
	disable_irq_nosync(pn547_dev->client->irq);
	atomic_set(&pn547_dev->irq_enabled, 0);

	gpio_set_value(pn547_dev->firm_gpio, 1); /* add firmware pin */
	msleep(20);
	gpio_set_value(pn547_dev->ven_gpio, 1);
	usleep_range(4900, 5000);
	gpio_set_value(pn547_dev->ven_gpio, 0);
	usleep_range(4900, 5000);
	gpio_set_value(pn547_dev->ven_gpio, 1);
	usleep_range(4900, 5000);

	gpio_set_value(pn547_dev->ven_gpio, 0);
	gpio_set_value(pn547_dev->firm_gpio, 0); /* add */

	if (ret < 0)
		pr_err("%s : fail to get i2c addr\n", __func__);
		/* goto err_request_irq_failed; */
	else
		pr_info("%s : success\n", __func__);
	return 0;

err_request_irq_failed:
	misc_deregister(&pn547_dev->pn547_device);
	wake_lock_destroy(&pn547_dev->nfc_wake_lock);
err_misc_register:
	mutex_destroy(&pn547_dev->read_mutex);
	kfree(pn547_dev);
err_exit:
	gpio_free(platform_data->firm_gpio);
err_firm:
	gpio_free(platform_data->ven_gpio);
err_ven:
	gpio_free(platform_data->irq_gpio);
	pr_err("[pn547] pn547_probe fail!\n");
	return ret;
}
Beispiel #2
0
int32_t msm_sensor_power_up(struct msm_sensor_ctrl_t *s_ctrl)
{
	int32_t rc = 0;
	struct msm_camera_sensor_info *data = s_ctrl->sensordata;
	CDBG("%s: %d\n", __func__, __LINE__);
	s_ctrl->reg_ptr = kzalloc(sizeof(struct regulator *)
			* data->sensor_platform_info->num_vreg, GFP_KERNEL);
	if (!s_ctrl->reg_ptr) {
		pr_err("%s: could not allocate mem for regulators\n",
			__func__);
		return -ENOMEM;
	}

	rc = msm_camera_request_gpio_table(data, 1);
	if (rc < 0) {
		pr_err("%s: request gpio failed\n", __func__);
		goto request_gpio_failed;
	}

	rc = msm_camera_config_vreg(&s_ctrl->sensor_i2c_client->client->dev,
			s_ctrl->sensordata->sensor_platform_info->cam_vreg,
			s_ctrl->sensordata->sensor_platform_info->num_vreg,
			s_ctrl->reg_ptr, 1);
	if (rc < 0) {
		pr_err("%s: regulator on failed\n", __func__);
		goto config_vreg_failed;
	}

	rc = msm_camera_enable_vreg(&s_ctrl->sensor_i2c_client->client->dev,
			s_ctrl->sensordata->sensor_platform_info->cam_vreg,
			s_ctrl->sensordata->sensor_platform_info->num_vreg,
			s_ctrl->reg_ptr, 1);
	if (rc < 0) {
		pr_err("%s: enable regulator failed\n", __func__);
		goto enable_vreg_failed;
	}

#ifndef CONFIG_PANTECH_CAMERA
	rc = msm_camera_config_gpio_table(data, 1);
	if (rc < 0) {
		pr_err("%s: config gpio failed\n", __func__);
		goto config_gpio_failed;
	}
#endif
	if (s_ctrl->clk_rate != 0)
		cam_clk_info->clk_rate = s_ctrl->clk_rate;

	rc = msm_cam_clk_enable(&s_ctrl->sensor_i2c_client->client->dev,
		cam_clk_info, &s_ctrl->cam_clk, ARRAY_SIZE(cam_clk_info), 1);
	if (rc < 0) {
		pr_err("%s: clk enable failed\n", __func__);
		goto enable_clk_failed;
	}

	usleep_range(1000, 2000);
	if (data->sensor_platform_info->ext_power_ctrl != NULL)
		data->sensor_platform_info->ext_power_ctrl(1);

	return rc;

enable_clk_failed:
#ifndef CONFIG_PANTECH_CAMERA
		msm_camera_config_gpio_table(data, 0);
config_gpio_failed:
#endif
	msm_camera_enable_vreg(&s_ctrl->sensor_i2c_client->client->dev,
			s_ctrl->sensordata->sensor_platform_info->cam_vreg,
			s_ctrl->sensordata->sensor_platform_info->num_vreg,
			s_ctrl->reg_ptr, 0);

enable_vreg_failed:
	msm_camera_config_vreg(&s_ctrl->sensor_i2c_client->client->dev,
		s_ctrl->sensordata->sensor_platform_info->cam_vreg,
		s_ctrl->sensordata->sensor_platform_info->num_vreg,
		s_ctrl->reg_ptr, 0);
config_vreg_failed:
	msm_camera_request_gpio_table(data, 0);
request_gpio_failed:
	kfree(s_ctrl->reg_ptr);
	return rc;
}
static void msm8960_enable_ext_spk_amp_gpio(u32 spk_amp_gpio)
{
	int ret = 0;

	struct pm_gpio param = {
		.direction      = PM_GPIO_DIR_OUT,
		.output_buffer  = PM_GPIO_OUT_BUF_CMOS,
		.output_value   = 1,
		.pull      = PM_GPIO_PULL_NO,
		.vin_sel	= PM_GPIO_VIN_S4,
		.out_strength   = PM_GPIO_STRENGTH_MED,
		.function       = PM_GPIO_FUNC_NORMAL,
	};

	if (spk_amp_gpio == BOTTOM_SPK_PAMP_GPIO) {

		ret = gpio_request(BOTTOM_SPK_PAMP_GPIO, "BOTTOM_SPK_AMP");
		if (ret) {
			pr_aud_err("%s: Error requesting BOTTOM SPK AMP GPIO %u\n",
				__func__, BOTTOM_SPK_PAMP_GPIO);
			return;
		}
		ret = pm8xxx_gpio_config(BOTTOM_SPK_PAMP_GPIO, &param);
		if (ret)
			pr_aud_err("%s: Failed to configure Bottom Spk Ampl"
				" gpio %u\n", __func__, BOTTOM_SPK_PAMP_GPIO);
		else {
			pr_debug("%s: enable spkr amp gpio\n", __func__);
			gpio_direction_output(BOTTOM_SPK_PAMP_GPIO, 1);
		}

	} else if (spk_amp_gpio == TOP_SPK_PAMP_GPIO) {

		ret = gpio_request(TOP_SPK_PAMP_GPIO, "TOP_SPK_AMP");
		if (ret) {
			pr_aud_err("%s: Error requesting GPIO %d\n", __func__,
				TOP_SPK_PAMP_GPIO);
			return;
		}
		ret = pm8xxx_gpio_config(TOP_SPK_PAMP_GPIO, &param);
		if (ret)
			pr_aud_err("%s: Failed to configure Top Spk Ampl"
				" gpio %u\n", __func__, TOP_SPK_PAMP_GPIO);
		else {
			pr_debug("%s: enable hac amp gpio\n", __func__);
			gpio_direction_output(TOP_SPK_PAMP_GPIO, 1);
		}

	} else if (spk_amp_gpio == DOCK_SPK_PAMP_GPIO) {

		ret = gpio_request(DOCK_SPK_PAMP_GPIO, "DOCK_SPK_AMP");
		if (ret) {
			pr_aud_err("%s: Error requesting GPIO %d\n", __func__,
				DOCK_SPK_PAMP_GPIO);
			return;
		}
		ret = pm8xxx_gpio_config(DOCK_SPK_PAMP_GPIO, &param);
		if (ret)
			pr_aud_err("%s: Failed to configure Dock Spk Ampl"
				" gpio %u\n", __func__, DOCK_SPK_PAMP_GPIO);
		else {
			pr_debug("%s: enable dock amp gpio\n", __func__);
			gpio_direction_output(DOCK_SPK_PAMP_GPIO, 1);
		}

		ret = gpio_request(USB_ID_ADC_GPIO, "USB_ID_ADC");
		if (ret) {
			pr_aud_err("%s: Error requesting USB_ID_ADC PMIC GPIO %u\n",
				__func__, USB_ID_ADC_GPIO);
			return;
		}
		ret = pm8xxx_gpio_config(USB_ID_ADC_GPIO, &param);
		if (ret)
			pr_aud_err("%s: Failed to configure USB_ID_ADC PMIC"
				" gpio %u\n", __func__, USB_ID_ADC_GPIO);

	} else {
		pr_aud_err("%s: ERROR : Invalid External Speaker Ampl GPIO."
			" gpio = %u\n", __func__, spk_amp_gpio);
		return;
	}
}

static void msm8960_ext_spk_power_amp_on(u32 spk)
{
	#ifdef CONFIG_AUDIO_USAGE_FOR_POWER_CONSUMPTION
	g_spk_flag = 1;
	g_spk_start_time = current_kernel_time();
	#endif

	if (spk & (BOTTOM_SPK_AMP_POS | BOTTOM_SPK_AMP_NEG)) {

		if ((msm8960_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_POS) &&
			(msm8960_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_NEG)) {

			pr_debug("%s() External Bottom Speaker Ampl already "
				"turned on. spk = 0x%08x\n", __func__, spk);
			return;
		}

		msm8960_ext_bottom_spk_pamp |= spk;

		if ((msm8960_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_POS) &&
			(msm8960_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_NEG)) {

			msm8960_enable_ext_spk_amp_gpio(BOTTOM_SPK_PAMP_GPIO);
			pr_debug("%s: slepping 4 ms after turning on external "
				" Speaker Ampl\n", __func__);
			usleep_range(4000, 4000);
		}

	} else if (spk & (TOP_SPK_AMP_POS | TOP_SPK_AMP_NEG)) {

		if ((msm8960_ext_top_spk_pamp & TOP_SPK_AMP_POS) &&
			(msm8960_ext_top_spk_pamp & TOP_SPK_AMP_NEG)) {

			pr_debug("%s() External Top Speaker Ampl already"
				"turned on. spk = 0x%08x\n", __func__, spk);
			return;
		}

		msm8960_ext_top_spk_pamp |= spk;

		if ((msm8960_ext_top_spk_pamp & TOP_SPK_AMP_POS) &&
			(msm8960_ext_top_spk_pamp & TOP_SPK_AMP_NEG)) {

			msm8960_enable_ext_spk_amp_gpio(TOP_SPK_PAMP_GPIO);
			pr_debug("%s: sleeping 4 ms after turning on "
				" external HAC Ampl\n", __func__);
			usleep_range(4000, 4000);
		}

	} else if (spk & (DOCK_SPK_AMP_POS | DOCK_SPK_AMP_NEG)) {

		mutex_lock(&audio_notifier_lock);

		if ((msm8960_ext_dock_spk_pamp & DOCK_SPK_AMP_POS) &&
			(msm8960_ext_dock_spk_pamp & DOCK_SPK_AMP_NEG)) {

			pr_debug("%s() External Dock Speaker Ampl already"
				"turned on. spk = 0x%08x\n", __func__, spk);
			return;
		}

		msm8960_ext_dock_spk_pamp |= spk;

		if ((msm8960_ext_dock_spk_pamp & DOCK_SPK_AMP_POS) &&
			(msm8960_ext_dock_spk_pamp & DOCK_SPK_AMP_NEG)) {

			msm8960_enable_ext_spk_amp_gpio(DOCK_SPK_PAMP_GPIO);

			pr_debug("%s: sleeping 4 ms after turning on "
				" external DOCK Ampl\n", __func__);
			usleep_range(4000, 4000);
		}
		mutex_unlock(&audio_notifier_lock);

	} else  {

		pr_aud_err("%s: ERROR : Invalid External Speaker Ampl. spk = 0x%08x\n",
			__func__, spk);
		return;
	}
}
u8 abov_byte_read(bool type, int scl, int sda)
{
	u8 i;
	u8 data = 0;
	u8 index = 0x7;

	gpio_direction_output(scl, 0);
	gpio_direction_input(sda);
	gpio_tlmm_config(GPIO_CFG(sda,0,GPIO_CFG_INPUT,GPIO_CFG_NO_PULL, GPIO_CFG_2MA), GPIO_CFG_ENABLE);
	usleep_range(20, 22);

	for (i = 0; i < 8; i++) {
		gpio_direction_output(scl, 0);
		usleep_range(10, 12);
		gpio_direction_output(scl, 1);
		usleep_range(5, 6);

		data = data | (u8)(gpio_get_value(sda) << index);
		index -= 1;
	}
	usleep_range(5, 6);
	gpio_direction_output(scl, 0);

	gpio_direction_output(sda, 0);
	usleep_range(5, 6);

	if (type) { /*ACK */
		gpio_direction_output(sda, 0);
		usleep_range(5, 6);
		gpio_direction_output(scl, 1);
		usleep_range(5, 6);
		gpio_direction_output(scl, 0);
		usleep_range(5, 6);
	} else { /* NAK */
		gpio_direction_output(sda, 1);
		usleep_range(5, 6);
		gpio_direction_output(scl, 1);
		usleep_range(10, 12);
		gpio_direction_output(scl, 0);
		usleep_range(5, 6);
		gpio_direction_output(sda, 0);
		usleep_range(5, 6);
	}
	usleep_range(20, 22);

	return data;
}
static void dw_mci_hs_set_ios(struct dw_mci *host, struct mmc_ios *ios)
{
	struct dw_mci_hs_priv_data *priv = host->priv;
	int id = priv->id;
	int ret;

	if (priv->old_power_mode != ios->power_mode) {
		switch (ios->power_mode) {
		case MMC_POWER_OFF:
			dev_info(host->dev, "set io to lowpower\n");

			/* set pin to idle, skip emmc for vccq keeping power always on */
			if (host->hw_mmc_id != DWMMC_EMMC_ID){
				if ((host->pinctrl) && (host->pins_idle)) {
					ret = pinctrl_select_state(host->pinctrl,
								   host->pins_idle);
					if (ret)
						dev_warn(host->dev,
							 "could not set idle pins\n");
				}
			}

			if (host->vqmmc)
				regulator_disable(host->vqmmc);

			if (host->vmmc)
				regulator_disable(host->vmmc);

			break;
		case MMC_POWER_UP:
			dev_info(host->dev, "set io to normal\n");

			if(host->hw_mmc_id != DWMMC_SD_ID) {
				if ((host->pinctrl) && (host->pins_default)) {
					ret = pinctrl_select_state(host->pinctrl,
								   host->pins_default);
					if (ret)
						dev_warn(
						    host->dev,
						    "could not set default pins\n");
				}
			}

			if (host->vmmc) {
				ret = regulator_set_voltage(host->vmmc, 2950000,
							    2950000);
				if (ret)
					dev_err(
					    host->dev,
					    "regulator_set_voltage failed !\n");

				ret = regulator_enable(host->vmmc);
				if (ret)
					dev_err(host->dev,
						"regulator_enable failed !\n");
			}

			if (host->vqmmc) {
				ret = regulator_set_voltage(host->vqmmc,
							    2950000, 2950000);
				if (ret)
					dev_err(
					    host->dev,
					    "regulator_set_voltage failed !\n");

				ret = regulator_enable(host->vqmmc);
				if (ret)
					dev_err(host->dev,
						"regulator_enable failed !\n");
			}

			if(host->hw_mmc_id == DWMMC_SD_ID) {

				/* Wait for 500us~1ms to avoid semi-high level of sdcard io ports */
				usleep_range(500, 1000);

				if ((host->pinctrl) && (host->pins_default)) {
					ret = pinctrl_select_state(host->pinctrl,
								   host->pins_default);
					if (ret)
						dev_warn(
						    host->dev,
						    "could not set default pins\n");
				}
			}

			break;
		case MMC_POWER_ON:
			break;
		default:
			dev_info(host->dev, "unknown power supply mode\n");
			break;
		}
		priv->old_power_mode = ios->power_mode;
	}

	if (priv->old_timing != ios->timing) {

		dw_mci_hs_set_parent(host, ios->timing);

		ret = clk_set_rate(host->ciu_clk,
				   hs_timing_config[id][ios->timing][0]);
		if (ret)
			dev_err(host->dev, "clk_set_rate failed\n");

		if (!priv->in_suspend)
			host->tuning_init_sample =
			    (hs_timing_config[id][ios->timing][4] +
			     hs_timing_config[id][ios->timing][5]) /
			    2;

		if (host->sd_reinit == 0)
			host->current_div =
			    hs_timing_config[id][ios->timing][1];

		dw_mci_hs_set_timing(host, id, ios->timing,
				     host->tuning_init_sample,
				     host->current_div);

		if (priv->priv_bus_hz == 0)
			host->bus_hz = hs_timing_config[id][ios->timing][6];
		else
			host->bus_hz = 2 * hs_timing_config[id][ios->timing][6];

		priv->old_timing = ios->timing;
	}
}
static int32_t qpnp_iadc_configure(enum qpnp_iadc_channels channel,
					uint16_t *raw_code, uint32_t mode_sel)
{
	struct qpnp_iadc_drv *iadc = qpnp_iadc;
	u8 qpnp_iadc_mode_reg = 0, qpnp_iadc_ch_sel_reg = 0;
	u8 qpnp_iadc_conv_req = 0, qpnp_iadc_dig_param_reg = 0;
	u8 status1 = 0;
	uint32_t count = 0;
	int32_t rc = 0;

	qpnp_iadc_ch_sel_reg = channel;

	qpnp_iadc_dig_param_reg |= iadc->adc->amux_prop->decimation <<
					QPNP_IADC_DEC_RATIO_SEL;
	if (iadc->iadc_mode_sel)
		qpnp_iadc_mode_reg |= (QPNP_ADC_TRIM_EN | QPNP_VADC_SYNCH_EN);
	else
		qpnp_iadc_mode_reg |= QPNP_ADC_TRIM_EN;

	qpnp_iadc_conv_req = QPNP_IADC_CONV_REQ;

	rc = qpnp_iadc_write_reg(QPNP_IADC_MODE_CTL, qpnp_iadc_mode_reg);
	if (rc) {
		pr_err("qpnp adc read adc failed with %d\n", rc);
		return rc;
	}

	rc = qpnp_iadc_write_reg(QPNP_IADC_ADC_CH_SEL_CTL,
						qpnp_iadc_ch_sel_reg);
	if (rc) {
		pr_err("qpnp adc read adc failed with %d\n", rc);
		return rc;
	}

	rc = qpnp_iadc_write_reg(QPNP_ADC_DIG_PARAM,
						qpnp_iadc_dig_param_reg);
	if (rc) {
		pr_err("qpnp adc read adc failed with %d\n", rc);
		return rc;
	}

	rc = qpnp_iadc_write_reg(QPNP_HW_SETTLE_DELAY,
				iadc->adc->amux_prop->hw_settle_time);
	if (rc < 0) {
		pr_err("qpnp adc configure error for hw settling time setup\n");
		return rc;
	}

	rc = qpnp_iadc_write_reg(QPNP_FAST_AVG_CTL,
					iadc->adc->amux_prop->fast_avg_setup);
	if (rc < 0) {
		pr_err("qpnp adc fast averaging configure error\n");
		return rc;
	}

	if (!iadc->iadc_poll_eoc)
		INIT_COMPLETION(iadc->adc->adc_rslt_completion);

	rc = qpnp_iadc_enable(true);
	if (rc)
		return rc;

	rc = qpnp_iadc_write_reg(QPNP_CONV_REQ, qpnp_iadc_conv_req);
	if (rc) {
		pr_err("qpnp adc read adc failed with %d\n", rc);
		return rc;
	}

	if (iadc->iadc_poll_eoc) {
		while (status1 != QPNP_STATUS1_EOC) {
			rc = qpnp_iadc_read_reg(QPNP_STATUS1, &status1);
			if (rc < 0)
				return rc;
			status1 &= QPNP_STATUS1_REQ_STS_EOC_MASK;
			usleep_range(QPNP_ADC_CONV_TIME_MIN,
					QPNP_ADC_CONV_TIME_MAX);
			count++;
			if (count > QPNP_ADC_ERR_COUNT) {
				pr_err("retry error exceeded\n");
				rc = qpnp_iadc_status_debug();
				if (rc < 0)
					pr_err("IADC status debug failed\n");
				rc = -EINVAL;
				return rc;
			}
		}
	} else {
		rc = wait_for_completion_timeout(
				&iadc->adc->adc_rslt_completion,
				QPNP_ADC_COMPLETION_TIMEOUT);
		if (!rc) {
			rc = qpnp_iadc_read_reg(QPNP_STATUS1, &status1);
			if (rc < 0)
				return rc;
			status1 &= QPNP_STATUS1_REQ_STS_EOC_MASK;
			if (status1 == QPNP_STATUS1_EOC)
				pr_debug("End of conversion status set\n");
			else {
				rc = qpnp_iadc_status_debug();
				if (rc < 0) {
					pr_err("status debug failed %d\n", rc);
					return rc;
				}
				return -EINVAL;
			}
		}
	}

	rc = qpnp_iadc_read_conversion_result(raw_code);
	if (rc) {
		pr_err("qpnp adc read adc failed with %d\n", rc);
		return rc;
	}

	return 0;
}
static int exynos_tmu_initialize(struct platform_device *pdev, int id)
{
	struct exynos_tmu_data *data = platform_get_drvdata(pdev);
	struct exynos_tmu_platform_data *pdata = data->pdata;
	unsigned int status, trim_info, rising_threshold, falling_threshold;
	int ret = 0, timeout =5, threshold_code;

	mutex_lock(&data->lock);
	clk_enable(data->clk);

	status = readb(data->base[id] + EXYNOS_TMU_REG_STATUS);
	if (!status) {
		ret = -EBUSY;
		goto out;
	}

	__raw_writel(EXYNOS_TRIMINFO_RELOAD1,
			data->base[id] + EXYNOS_TMU_TRIMINFO_CON1);
	__raw_writel(EXYNOS_TRIMINFO_RELOAD2,
			data->base[id] + EXYNOS_TMU_TRIMINFO_CON2);

	while(readl(data->base[id] + EXYNOS_TMU_TRIMINFO_CON2) & EXYNOS_TRIMINFO_RELOAD1) {
		if(!timeout) {
			pr_err("Thermal TRIMINFO register reload failed\n");
			break;
		}
		timeout--;
		cpu_relax();
		usleep_range(5,10);
	}
	/* Save trimming info in order to perform calibration */
	trim_info = readl(data->base[id] + EXYNOS_TMU_REG_TRIMINFO);
	data->temp_error1 = trim_info & EXYNOS_TMU_TRIM_TEMP_MASK;
	data->temp_error2 = ((trim_info >> 8) & EXYNOS_TMU_TRIM_TEMP_MASK);

	if ((EFUSE_MIN_VALUE > data->temp_error1) ||
			(data->temp_error1 > EFUSE_MAX_VALUE) ||
			(data->temp_error2 != 0))
		data->temp_error1 = pdata->efuse_value;

	/* Write temperature code for threshold */
	threshold_code = temp_to_code(data, pdata->threshold +
			pdata->trigger_levels[0]);
	if (threshold_code < 0) {
		ret = threshold_code;
		goto out;
	}
	rising_threshold = threshold_code;
	falling_threshold = threshold_code - GAP_WITH_RISE;
	threshold_code = temp_to_code(data, pdata->threshold +
			pdata->trigger_levels[1]);
	if (threshold_code < 0) {
		ret = threshold_code;
		goto out;
	}
	rising_threshold |= (threshold_code << THRESH_LEVE1_SHIFT);
	falling_threshold |= ((threshold_code - GAP_WITH_RISE) << THRESH_LEVE1_SHIFT);
	threshold_code = temp_to_code(data, pdata->threshold +
			pdata->trigger_levels[2]);
	if (threshold_code < 0) {
		ret = threshold_code;
		goto out;
	}
	rising_threshold |= (threshold_code << THRESH_LEVE2_SHIFT);
	falling_threshold |= ((threshold_code - GAP_WITH_RISE) << THRESH_LEVE2_SHIFT);
	threshold_code = temp_to_code(data, pdata->threshold +
			pdata->trigger_levels[3]);
	if (threshold_code < 0) {
		ret = threshold_code;
		goto out;
	}
	rising_threshold |= (threshold_code << THRESH_LEVE3_SHIFT);

	writel(rising_threshold,
			data->base[0] + EXYNOS4270_TMU_THRESHOLD_TEMP_RISE);
	writel(falling_threshold, data->base[0] + EXYNOS4270_TMU_THRESHOLD_TEMP_FALL);
	writel(EXYNOS4270_TMU_CLEAR_RISE_INT | EXYNOS4270_TMU_CLEAR_FALL_INT,
			data->base[0] + EXYNOS_TMU_REG_INTCLEAR);

out:
	clk_disable(data->clk);
	mutex_unlock(&data->lock);

	return ret;
}
static int s6e8fa0_ldi_init(struct lcd_info *lcd)
{
	int ret = 0;
	char lcd_buf[3] = {0,};
	char lcd_count = 0;
	unsigned char evt1_check = 0x20;

	s6e8fa0_write(lcd, SEQ_TEST_KEY_ON_F0, ARRAY_SIZE(SEQ_TEST_KEY_ON_F0));

	/*EVT1 check*/
	if ((lcd->id[2] & evt1_check) != evt1_check) {
		for (lcd_count = 0; lcd_count < 15; lcd_count++) {
			s6e8fa0_read(lcd, SEQ_TEST_KEY_ON_F0[0], lcd_buf, ARRAY_SIZE(SEQ_TEST_KEY_ON_F0));

			printk(KERN_INFO "EVT 0 lcd_check = %x, lcd_count = %d\n", lcd_buf[1], lcd_count);

			if (lcd_buf[1] == 0x5A)
				break;

			msleep(100);

			s6e8fa0_write(lcd, SEQ_TEST_KEY_ON_F0, ARRAY_SIZE(SEQ_TEST_KEY_ON_F0));
		}
	}

	s6e8fa0_write(lcd, SEQ_TEST_KEY_ON_F1, ARRAY_SIZE(SEQ_TEST_KEY_ON_F1));
	s6e8fa0_write(lcd, SEQ_TEST_KEY_ON_FC, ARRAY_SIZE(SEQ_TEST_KEY_ON_FC));

	if (lcd->id[2] == 0x03)
		s6e8fa0_write(lcd, SEQ_SCAN_TIMMING_1_FE, ARRAY_SIZE(SEQ_SCAN_TIMMING_1_FE));

	usleep_range(17000, 17000); /*wait 1 frame*/

	s6e8fa0_write(lcd, SEQ_SLEEP_OUT, ARRAY_SIZE(SEQ_SLEEP_OUT));
	s6e8fa0_write(lcd, SEQ_ERROR_FLAG_ON, ARRAY_SIZE(SEQ_ERROR_FLAG_ON));

	msleep(25);

	s6e8fa0_write(lcd, SEQ_LTPS_F2, ARRAY_SIZE(SEQ_LTPS_F2));
	s6e8fa0_write(lcd, SEQ_LTPS_B0, ARRAY_SIZE(SEQ_LTPS_B0));
	s6e8fa0_write(lcd, SEQ_LTPS_CB, ARRAY_SIZE(SEQ_LTPS_CB));
	s6e8fa0_write(lcd, SEQ_LTPS_F7, ARRAY_SIZE(SEQ_LTPS_F7));

	msleep(100);

	if (lcd->id[2] == 0x03) {
		s6e8fa0_write(lcd, SEQ_SCAN_TIMMING_2_FD, ARRAY_SIZE(SEQ_SCAN_TIMMING_2_FD));
		s6e8fa0_write(lcd, SEQ_SCAN_TIMMING_2_C0, ARRAY_SIZE(SEQ_SCAN_TIMMING_2_C0));
		s6e8fa0_write(lcd, SEQ_SCAN_TIMMING_2_F4, ARRAY_SIZE(SEQ_SCAN_TIMMING_2_F4));
	}
	s6e8fa0_write(lcd, SEQ_SCAN_TIMMING_2_F6, ARRAY_SIZE(SEQ_SCAN_TIMMING_2_F6));

	s6e8fa0_gamma_ctl(lcd);
	s6e8fa0_write(lcd, SEQ_AOR_CONTROL, ARRAY_SIZE(SEQ_AOR_CONTROL));
	s6e8fa0_write(lcd, SEQ_GAMMA_UPDATE, ARRAY_SIZE(SEQ_GAMMA_UPDATE));
	s6e8fa0_write(lcd, SEQ_ELVSS_CONDITION_SET, ARRAY_SIZE(SEQ_ELVSS_CONDITION_SET));
#ifdef PSRE_HBM
	s6e8fa0_write(lcd, SEQ_PSRE_MODE_OFF, ARRAY_SIZE(SEQ_PSRE_MODE_OFF));
	lcd->hbm_enable  = 0;
#endif
	s6e8fa0_write(lcd, SEQ_ACL_OFF, ARRAY_SIZE(SEQ_ACL_OFF));
#ifdef PSRE_HBM
	s6e8fa0_write(lcd, SEQ_PSRE_MODE_SET2, ARRAY_SIZE(SEQ_PSRE_MODE_SET2));
	s6e8fa0_write(lcd, SEQ_PSRE_MODE_SET3, ARRAY_SIZE(SEQ_PSRE_MODE_SET3));
#endif
	usleep_range(17000, 17000); /*wait 1 frame*/

	s6e8fa0_write(lcd, SEQ_DISPLAY_ON, ARRAY_SIZE(SEQ_DISPLAY_ON));

	return ret;
}
static int imx135_power_ctrl(struct v4l2_subdev *sd, int flag)
{
	struct i2c_client *client = v4l2_get_subdevdata(sd);
	int ret = 0;

	if (flag) {
		if (is_ctp()) {
			if (!camera_vemmc1_on) {

				camera_vemmc1_on = 1;
				ret = regulator_enable(vemmc1_reg);
				if (ret) {
					dev_err(&client->dev,
						"Failed to enable regulator vemmc1\n");
					return ret;
				}

			}
			if (vprog1_reg && !camera_vprog1_on) {
				camera_vprog1_on = 1;
				ret = regulator_enable(vprog1_reg);
				if (ret) {
					dev_err(&client->dev,
						"Failed to enable regulator vprog1\n");
					return ret;
				}

			}
			if (!is_victoriabay()) {
				if (camera_power < 0) {
					ret = camera_sensor_gpio(-1,
						GP_CAMERA_1_POWER_DOWN,
						GPIOF_DIR_OUT, 1);
					if (ret < 0)
						return ret;
					camera_power = ret;
				}
				gpio_set_value(camera_power, 1);
			}
			/* min 250us -Initializing time of silicon */
			usleep_range(250, 300);
		} else {
			if (!camera_vprog1_on) {
				ret = regulator_enable(vprog1_reg);
				if (!ret) {
					/* imx1x5 VDIG rise to XCLR release */
					usleep_range(1000, 1200);
					camera_vprog1_on = 1;
				}
				return ret;
			}
		}
	} else {
		if (is_ctp()) {
			if (camera_vemmc1_on) {
				camera_vemmc1_on = 0;

				ret = regulator_disable(vemmc1_reg);
				if (ret) {
					dev_err(&client->dev,
						"Failed to disable regulator vemmc1\n");
					return ret;
				}
			}
			if (vprog1_reg && camera_vprog1_on) {
				camera_vprog1_on = 0;

				ret = regulator_disable(vprog1_reg);
				if (ret) {
					dev_err(&client->dev,
						"Failed to disable regulator vprog1\n");
					return ret;
				}
			}
		} else {
			if (camera_vprog1_on) {
				ret = regulator_disable(vprog1_reg);
				if (!ret)
					camera_vprog1_on = 0;
				return ret;
			}
		}
	}
	return 0;
}
Beispiel #10
0
static int isl29018_chip_init(struct isl29018_chip *chip)
{
	int status;
	struct device *dev = regmap_get_device(chip->regmap);

	if (chip->type == isl29035) {
		status = isl29035_detect(chip);
		if (status < 0)
			return status;
	}

	/* Code added per Intersil Application Note 1534:
	 *     When VDD sinks to approximately 1.8V or below, some of
	 * the part's registers may change their state. When VDD
	 * recovers to 2.25V (or greater), the part may thus be in an
	 * unknown mode of operation. The user can return the part to
	 * a known mode of operation either by (a) setting VDD = 0V for
	 * 1 second or more and then powering back up with a slew rate
	 * of 0.5V/ms or greater, or (b) via I2C disable all ALS/PROX
	 * conversions, clear the test registers, and then rewrite all
	 * registers to the desired values.
	 * ...
	 * For ISL29011, ISL29018, ISL29021, ISL29023
	 * 1. Write 0x00 to register 0x08 (TEST)
	 * 2. Write 0x00 to register 0x00 (CMD1)
	 * 3. Rewrite all registers to the desired values
	 *
	 * ISL29018 Data Sheet (FN6619.1, Feb 11, 2010) essentially says
	 * the same thing EXCEPT the data sheet asks for a 1ms delay after
	 * writing the CMD1 register.
	 */
	status = regmap_write(chip->regmap, ISL29018_REG_TEST, 0x0);
	if (status < 0) {
		dev_err(dev, "Failed to clear isl29018 TEST reg.(%d)\n",
			status);
		return status;
	}

	/* See Intersil AN1534 comments above.
	 * "Operating Mode" (COMMAND1) register is reprogrammed when
	 * data is read from the device.
	 */
	status = regmap_write(chip->regmap, ISL29018_REG_ADD_COMMAND1, 0);
	if (status < 0) {
		dev_err(dev, "Failed to clear isl29018 CMD1 reg.(%d)\n",
			status);
		return status;
	}

	usleep_range(1000, 2000);	/* per data sheet, page 10 */

	/* Set defaults */
	status = isl29018_set_scale(chip, chip->scale.scale,
				    chip->scale.uscale);
	if (status < 0) {
		dev_err(dev, "Init of isl29018 fails\n");
		return status;
	}

	status = isl29018_set_integration_time(chip,
			isl29018_int_utimes[chip->type][chip->int_time]);
	if (status < 0) {
		dev_err(dev, "Init of isl29018 fails\n");
		return status;
	}

	return 0;
}
Beispiel #11
0
static ssize_t pn65n_dev_read(struct file *filp, char __user *buf,
			      size_t count, loff_t *offset)
{
	struct pn65n_dev *pn65n_dev = filp->private_data;
	char tmp[MAX_BUFFER_SIZE];
	int ret = 0;
	int readingWatchdog = 0;

	if (count > MAX_BUFFER_SIZE)
		count = MAX_BUFFER_SIZE;

#if NFC_DEBUG
	dev_info(&pn65n_dev->client->dev, "%s : reading %zu bytes. irq=%s\n",
		__func__, count,
		gpio_get_value(pn65n_dev->irq_gpio) ? "1" : "0");
	dev_info(&pn65n_dev->client->dev, "pn65n : + r\n");
#endif

	mutex_lock(&pn65n_dev->read_mutex);

wait_irq:
	if (!gpio_get_value(pn65n_dev->irq_gpio)) {
#ifdef NXP_KR_READ_IRQ_MODIFY
		do_reading = false;
#endif
		if (filp->f_flags & O_NONBLOCK) {
			dev_info(&pn65n_dev->client->dev, "%s : O_NONBLOCK\n",
				 __func__);
			ret = -EAGAIN;
			goto fail;
		}
#if NFC_DEBUG
		dev_info(&pn65n_dev->client->dev,
			"wait_event_interruptible : in\n");
#endif

#ifdef NXP_KR_READ_IRQ_MODIFY
		ret = wait_event_interruptible(pn65n_dev->read_wq,
			do_reading);
#else
		ret = wait_event_interruptible(pn65n_dev->read_wq,
			gpio_get_value(pn65n_dev->irq_gpio));
#endif

#if NFC_DEBUG
		dev_info(&pn65n_dev->client->dev,
			"wait_event_interruptible : out\n");
#endif

#ifdef NXP_KR_READ_IRQ_MODIFY
		if (cancle_read == true) {
			cancle_read = false;
			ret = -1;
			goto fail;
		}
#endif

		if (ret)
			goto fail;
	}

	/* Read data */
	ret = i2c_master_recv(pn65n_dev->client, tmp, count);

	/* If bad frame(from 0x51 to 0x57) is received from pn65n,
	* we need to read again after waiting that IRQ is down.
	* if data is not ready, pn65n will send from 0x51 to 0x57. */
	if ((I2C_ADDR_READ_L <= tmp[0] && tmp[0] <= I2C_ADDR_READ_H)
		&& readingWatchdog < MAX_TRY_I2C_READ) {
		pr_warn("%s: data is not ready yet.data = 0x%x, cnt=%d\n",
			__func__, tmp[0], readingWatchdog);
		usleep_range(2000, 2000); /* sleep 2ms to wait for IRQ */
		readingWatchdog++;
		goto wait_irq;
	}

	mutex_unlock(&pn65n_dev->read_mutex);

	if (ret < 0) {
		dev_err(&pn65n_dev->client->dev,
			"%s: i2c_master_recv returned %d\n",
				__func__, ret);
		return ret;
	}
	if (ret > count) {
		dev_err(&pn65n_dev->client->dev,
			"%s: received too many bytes from i2c (%d)\n",
			__func__, ret);
		return -EIO;
	}

	if (copy_to_user(buf, tmp, ret)) {
		dev_err(&pn65n_dev->client->dev,
			"%s : failed to copy to user space\n",
			__func__);
		return -EFAULT;
	}
	return ret;

fail:
	mutex_unlock(&pn65n_dev->read_mutex);
	return ret;
}
Beispiel #12
0
static long pn65n_dev_ioctl(struct file *filp,
			    unsigned int cmd, unsigned long arg)
{
	struct pn65n_dev *pn65n_dev = filp->private_data;

	switch (cmd) {
	case PN65N_SET_PWR:
		if (arg == 2) {
			/* power on with firmware download (requires hw reset)
			 */
			gpio_set_value(pn65n_dev->ven_gpio, 1);
			gpio_set_value(pn65n_dev->firm_gpio, 1);
			usleep_range(10000, 10000);
			gpio_set_value(pn65n_dev->ven_gpio, 0);
			usleep_range(10000, 10000);
			gpio_set_value(pn65n_dev->ven_gpio, 1);
			usleep_range(10000, 10000);
			if (atomic_read(&pn65n_dev->irq_enabled) == 0) {
				atomic_set(&pn65n_dev->irq_enabled, 1);
				enable_irq(pn65n_dev->client->irq);
				enable_irq_wake(pn65n_dev->client->irq);
			}
			dev_info(&pn65n_dev->client->dev,
				 "%s power on with firmware, irq=%d\n",
				 __func__,
				 atomic_read(&pn65n_dev->irq_enabled));
		} else if (arg == 1) {
			/* power on */
			gpio_set_value(pn65n_dev->firm_gpio, 0);
			gpio_set_value(pn65n_dev->ven_gpio, 1);
			usleep_range(10000, 10000);
			if (atomic_read(&pn65n_dev->irq_enabled) == 0) {
				atomic_set(&pn65n_dev->irq_enabled, 1);
				enable_irq(pn65n_dev->client->irq);
				enable_irq_wake(pn65n_dev->client->irq);
			}
			dev_info(&pn65n_dev->client->dev,
				"%s power on, irq=%d\n", __func__,
				atomic_read(&pn65n_dev->irq_enabled));
		} else if (arg == 0) {
			/* power off */
			if (atomic_read(&pn65n_dev->irq_enabled) == 1) {
				disable_irq_wake(pn65n_dev->client->irq);
				disable_irq_nosync(pn65n_dev->client->irq);
				atomic_set(&pn65n_dev->irq_enabled, 0);
			}
			dev_info(&pn65n_dev->client->dev, "%s power off, irq=%d\n",
				 __func__,
				 atomic_read(&pn65n_dev->irq_enabled));
			gpio_set_value(pn65n_dev->firm_gpio, 0);
			gpio_set_value(pn65n_dev->ven_gpio, 0);
			usleep_range(10000, 10000);
#ifdef NXP_KR_READ_IRQ_MODIFY
		} else if (arg == 3) {
			pr_info("%s Read Cancle\n", __func__);
			cancle_read = true;
			do_reading = true;
			wake_up(&pn65n_dev->read_wq);
#endif
		} else {
			dev_err(&pn65n_dev->client->dev, "%s bad arg %lu\n",
				__func__, arg);
			return -EINVAL;
		}
		break;
	default:
		dev_err(&pn65n_dev->client->dev, "%s bad ioctl %u\n", __func__,
			cmd);
		return -EINVAL;
	}

	return 0;
}
static int t4k35_180_power_ctrl(struct v4l2_subdev *sd, int flag)
{
	int reg_err;
	int ret = 0;

	printk("%s: ++\n",__func__);

	if (camera_reset < 0) {
		ret = camera_sensor_gpio(-1, GP_CAMERA_0_RESET, GPIOF_DIR_OUT, 0);
		if (ret < 0){
			printk("camera_reset not available.\n");
			return ret;
		}
		camera_reset = ret;
	}

	printk("<< camera_reset:%d, flag:%d\n", camera_reset, flag);

	if (flag) {
		if (camera_reset >= 0){
			gpio_set_value(camera_reset, 0);
			printk("<<< camera_reset = 0\n");
		}

		//turn on VCM power 2.85V
		if (!camera_vemmc1_on) {
			camera_vemmc1_on = 1;
			reg_err = regulator_enable(vemmc1_reg);
			if (reg_err) {
				printk(KERN_ALERT "Failed to enable regulator vemmc1\n");
				return reg_err;
			}
			printk("<<< VCM 2.85V = 1\n");
		}

		//turn on power 1.8V and 2.8V
		if (!camera_vprog1_on) {
			camera_vprog1_on = 1;
			reg_err = regulator_enable(vprog1_reg);
			if (reg_err) {
				printk(KERN_ALERT "Failed to enable regulator vprog1\n");
				return reg_err;
			}
			printk("<<< 1.8V and 2.8V = 1\n");
		}

		//turn on power 1.2V
		if (!camera_vprog2_on) {
			camera_vprog2_on = 1;
			reg_err = regulator_enable(vprog2_reg);
			if (reg_err) {
				printk(KERN_ALERT "Failed to enable regulator vprog2\n");
				return reg_err;
			}
			printk("<<< 1.2V = 1\n");
		}

		usleep_range(2000, 2100); //wait vprog1 and vprog2 from enable to 90% (max:2000us)
	} else {
		if (camera_reset >= 0){
			gpio_free(camera_reset);
			camera_reset = -1;
		}

		//turn off power 1.2V
		if (camera_vprog2_on) {
			camera_vprog2_on = 0;
			reg_err = regulator_disable(vprog2_reg);
			if (reg_err) {
				printk(KERN_ALERT "Failed to disable regulator vprog2\n");
				return reg_err;
			}
			printk("<<< 1.2V = 0\n");
		}

		//turn off power 1.8V and 2.8V
		if (camera_vprog1_on) {
			camera_vprog1_on = 0;
			reg_err = regulator_disable(vprog1_reg);
			if (reg_err) {
				printk(KERN_ALERT "Failed to disable regulator vprog1\n");
				return reg_err;
			}
			printk("<<< 1.8V and 2.8V = 0\n");
		}

		//turn off VCM power 2.85V
		if (camera_vemmc1_on) {
			camera_vemmc1_on = 0;
			reg_err = regulator_disable(vemmc1_reg);
			if (reg_err) {
				printk(KERN_ALERT "Failed to disable regulator vemmc1\n");
				return reg_err;
			}
			printk("<<< VCM 2.85V = 0\n");
		}
	}
	return 0;
}
Beispiel #14
0
static void msm8960_enable_ext_spk_amp_gpio(u32 spk_amp_gpio)
{
	int ret = 0;

	struct pm_gpio param = {
		.direction      = PM_GPIO_DIR_OUT,
		.output_buffer  = PM_GPIO_OUT_BUF_CMOS,
		.output_value   = 1,
		.pull      = PM_GPIO_PULL_NO,
		.vin_sel	= PM_GPIO_VIN_S4,
		.out_strength   = PM_GPIO_STRENGTH_MED,
		.
			function       = PM_GPIO_FUNC_NORMAL,
	};

	if (spk_amp_gpio == bottom_spk_pamp_gpio) {

		ret = gpio_request(bottom_spk_pamp_gpio, "BOTTOM_SPK_AMP");
		if (ret) {
			pr_err("%s: Error requesting BOTTOM SPK AMP GPIO %u\n",
				__func__, bottom_spk_pamp_gpio);
			return;
		}
		ret = pm8xxx_gpio_config(bottom_spk_pamp_gpio, &param);
		if (ret)
			pr_err("%s: Failed to configure Bottom Spk Ampl"
				" gpio %u\n", __func__, bottom_spk_pamp_gpio);
		else {
			pr_debug("%s: enable Bottom spkr amp gpio\n", __func__);
			gpio_direction_output(bottom_spk_pamp_gpio, 1);
		}

	} else if (spk_amp_gpio == top_spk_pamp_gpio) {

		ret = gpio_request(top_spk_pamp_gpio, "TOP_SPK_AMP");
		if (ret) {
			pr_err("%s: Error requesting GPIO %d\n", __func__,
				top_spk_pamp_gpio);
			return;
		}
		ret = pm8xxx_gpio_config(top_spk_pamp_gpio, &param);
		if (ret)
			pr_err("%s: Failed to configure Top Spk Ampl"
				" gpio %u\n", __func__, top_spk_pamp_gpio);
		else {
			pr_debug("%s: enable Top spkr amp gpio\n", __func__);
			gpio_direction_output(top_spk_pamp_gpio, 1);
		}
	} else {
		pr_err("%s: ERROR : Invalid External Speaker Ampl GPIO."
			" gpio = %u\n", __func__, spk_amp_gpio);
		return;
	}
}

static void msm8960_ext_spk_power_amp_on(u32 spk)
{
	if (spk & (BOTTOM_SPK_AMP_POS | BOTTOM_SPK_AMP_NEG)) {

		if ((msm8960_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_POS) &&
			(msm8960_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_NEG)) {

			pr_debug("%s() External Bottom Speaker Ampl already "
				"turned on. spk = 0x%08x\n", __func__, spk);
			return;
		}

		msm8960_ext_bottom_spk_pamp |= spk;

		if ((msm8960_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_POS) &&
			(msm8960_ext_bottom_spk_pamp & BOTTOM_SPK_AMP_NEG)) {

			msm8960_enable_ext_spk_amp_gpio(bottom_spk_pamp_gpio);
			pr_debug("%s: slepping 4 ms after turning on external "
				" Bottom Speaker Ampl\n", __func__);
			usleep_range(4000, 4000);
		}

	} else if  (spk & (TOP_SPK_AMP_POS | TOP_SPK_AMP_NEG | TOP_SPK_AMP)) {

		pr_debug("%s: top_spk_amp_state = 0x%x spk_event = 0x%x\n",
			__func__, msm8960_ext_top_spk_pamp, spk);

		if (((msm8960_ext_top_spk_pamp & TOP_SPK_AMP_POS) &&
			(msm8960_ext_top_spk_pamp & TOP_SPK_AMP_NEG)) ||
				(msm8960_ext_top_spk_pamp & TOP_SPK_AMP)) {

			pr_debug("%s() External Top Speaker Ampl already"
				"turned on. spk = 0x%08x\n", __func__, spk);
			return;
		}

		msm8960_ext_top_spk_pamp |= spk;

		if (((msm8960_ext_top_spk_pamp & TOP_SPK_AMP_POS) &&
			(msm8960_ext_top_spk_pamp & TOP_SPK_AMP_NEG)) ||
				(msm8960_ext_top_spk_pamp & TOP_SPK_AMP)) {

			msm8960_enable_ext_spk_amp_gpio(top_spk_pamp_gpio);
			pr_debug("%s: sleeping 4 ms after turning on "
				" external Top Speaker Ampl\n", __func__);
			usleep_range(4000, 4000);
		}
	} else  {

		pr_err("%s: ERROR : Invalid External Speaker Ampl. spk = 0x%08x\n",
			__func__, spk);
		return;
	}
}

static void msm8960_ext_spk_power_amp_off(u32 spk)
{
	if (spk & (BOTTOM_SPK_AMP_POS | BOTTOM_SPK_AMP_NEG)) {

		if (!msm8960_ext_bottom_spk_pamp)
			return;

		gpio_direction_output(bottom_spk_pamp_gpio, 0);
		gpio_free(bottom_spk_pamp_gpio);
		msm8960_ext_bottom_spk_pamp = 0;

		pr_debug("%s: sleeping 4 ms after turning off external Bottom"
			" Speaker Ampl\n", __func__);

		usleep_range(4000, 4000);

	} else if (spk & (TOP_SPK_AMP_POS | TOP_SPK_AMP_NEG | TOP_SPK_AMP)) {

		pr_debug("%s: top_spk_amp_state = 0x%x spk_event = 0x%x\n",
				__func__, msm8960_ext_top_spk_pamp, spk);

		if (!msm8960_ext_top_spk_pamp)
			return;

		if ((spk & TOP_SPK_AMP_POS) || (spk & TOP_SPK_AMP_NEG)) {

			msm8960_ext_top_spk_pamp &= (~(TOP_SPK_AMP_POS |
							TOP_SPK_AMP_NEG));
		} else if (spk & TOP_SPK_AMP) {
			msm8960_ext_top_spk_pamp &=  ~TOP_SPK_AMP;
		}

		if (msm8960_ext_top_spk_pamp)
			return;

		gpio_direction_output(top_spk_pamp_gpio, 0);
		gpio_free(top_spk_pamp_gpio);
		msm8960_ext_top_spk_pamp = 0;

		pr_debug("%s: sleeping 4 ms after ext Top Spek Ampl is off\n",
				__func__);

		usleep_range(4000, 4000);
	} else  {

		pr_err("%s: ERROR : Invalid Ext Spk Ampl. spk = 0x%08x\n",
			__func__, spk);
		return;
	}
}

static void msm8960_ext_control(struct snd_soc_codec *codec)
{
	struct snd_soc_dapm_context *dapm = &codec->dapm;

	mutex_lock(&dapm->codec->mutex);

	pr_debug("%s: msm8960_spk_control = %d", __func__, msm8960_spk_control);
	if (msm8960_spk_control == MSM8960_SPK_ON) {
		snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Pos");
		snd_soc_dapm_enable_pin(dapm, "Ext Spk Bottom Neg");
		snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Pos");
		snd_soc_dapm_enable_pin(dapm, "Ext Spk Top Neg");
	} else {
		snd_soc_dapm_disable_pin(dapm, "Ext Spk Bottom Pos");
		snd_soc_dapm_disable_pin(dapm, "Ext Spk Bottom Neg");
		snd_soc_dapm_disable_pin(dapm, "Ext Spk Top Pos");
		snd_soc_dapm_disable_pin(dapm, "Ext Spk Top Neg");
	}

	snd_soc_dapm_sync(dapm);
	mutex_unlock(&dapm->codec->mutex);
}

static int msm8960_get_spk(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	pr_debug("%s: msm8960_spk_control = %d", __func__, msm8960_spk_control);
	ucontrol->value.integer.value[0] = msm8960_spk_control;
	return 0;
}
Beispiel #15
0
static int mt9m032_setup_pll(struct mt9m032 *sensor)
{
	static const struct aptina_pll_limits limits = {
		.ext_clock_min = 8000000,
		.ext_clock_max = 16500000,
		.int_clock_min = 2000000,
		.int_clock_max = 24000000,
		.out_clock_min = 322000000,
		.out_clock_max = 693000000,
		.pix_clock_max = 99000000,
		.n_min = 1,
		.n_max = 64,
		.m_min = 16,
		.m_max = 255,
		.p1_min = 6,
		.p1_max = 7,
	};

	struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
	struct mt9m032_platform_data *pdata = sensor->pdata;
	struct aptina_pll pll;
	u16 reg_val;
	int ret;

	pll.ext_clock = pdata->ext_clock;
	pll.pix_clock = pdata->pix_clock;

	ret = aptina_pll_calculate(&client->dev, &limits, &pll);
	if (ret < 0)
		return ret;

	sensor->pix_clock = pdata->pix_clock;

	ret = mt9m032_write(client, MT9M032_PLL_CONFIG1,
			    (pll.m << MT9M032_PLL_CONFIG1_MUL_SHIFT) |
			    ((pll.n - 1) & MT9M032_PLL_CONFIG1_PREDIV_MASK));
	if (!ret)
		ret = mt9m032_write(client, MT9P031_PLL_CONTROL,
				    MT9P031_PLL_CONTROL_PWRON |
				    MT9P031_PLL_CONTROL_USEPLL);
	if (!ret)		/* more reserved, Continuous, Master Mode */
		ret = mt9m032_write(client, MT9M032_READ_MODE1, 0x8000 |
				    MT9M032_READ_MODE1_STROBE_START_EXP |
				    MT9M032_READ_MODE1_STROBE_END_SHUTTER);
	if (!ret) {
		reg_val = (pll.p1 == 6 ? MT9M032_FORMATTER1_PLL_P1_6 : 0)
			| MT9M032_FORMATTER1_PARALLEL | 0x001e; /* 14-bit */
		ret = mt9m032_write(client, MT9M032_FORMATTER1, reg_val);
	}

	return ret;
}

/* -----------------------------------------------------------------------------
 * Subdev pad operations
 */

static int mt9m032_enum_mbus_code(struct v4l2_subdev *subdev,
				  struct v4l2_subdev_fh *fh,
				  struct v4l2_subdev_mbus_code_enum *code)
{
	if (code->index != 0)
		return -EINVAL;

	code->code = V4L2_MBUS_FMT_Y8_1X8;
	return 0;
}

static int mt9m032_enum_frame_size(struct v4l2_subdev *subdev,
				   struct v4l2_subdev_fh *fh,
				   struct v4l2_subdev_frame_size_enum *fse)
{
	if (fse->index != 0 || fse->code != V4L2_MBUS_FMT_Y8_1X8)
		return -EINVAL;

	fse->min_width = MT9M032_COLUMN_SIZE_DEF;
	fse->max_width = MT9M032_COLUMN_SIZE_DEF;
	fse->min_height = MT9M032_ROW_SIZE_DEF;
	fse->max_height = MT9M032_ROW_SIZE_DEF;

	return 0;
}

/**
 * __mt9m032_get_pad_crop() - get crop rect
 * @sensor: pointer to the sensor struct
 * @fh: file handle for getting the try crop rect from
 * @which: select try or active crop rect
 *
 * Returns a pointer the current active or fh relative try crop rect
 */
static struct v4l2_rect *
__mt9m032_get_pad_crop(struct mt9m032 *sensor, struct v4l2_subdev_fh *fh,
		       enum v4l2_subdev_format_whence which)
{
	switch (which) {
	case V4L2_SUBDEV_FORMAT_TRY:
		return v4l2_subdev_get_try_crop(fh, 0);
	case V4L2_SUBDEV_FORMAT_ACTIVE:
		return &sensor->crop;
	default:
		return NULL;
	}
}

/**
 * __mt9m032_get_pad_format() - get format
 * @sensor: pointer to the sensor struct
 * @fh: file handle for getting the try format from
 * @which: select try or active format
 *
 * Returns a pointer the current active or fh relative try format
 */
static struct v4l2_mbus_framefmt *
__mt9m032_get_pad_format(struct mt9m032 *sensor, struct v4l2_subdev_fh *fh,
			 enum v4l2_subdev_format_whence which)
{
	switch (which) {
	case V4L2_SUBDEV_FORMAT_TRY:
		return v4l2_subdev_get_try_format(fh, 0);
	case V4L2_SUBDEV_FORMAT_ACTIVE:
		return &sensor->format;
	default:
		return NULL;
	}
}

static int mt9m032_get_pad_format(struct v4l2_subdev *subdev,
				  struct v4l2_subdev_fh *fh,
				  struct v4l2_subdev_format *fmt)
{
	struct mt9m032 *sensor = to_mt9m032(subdev);

	mutex_lock(&sensor->lock);
	fmt->format = *__mt9m032_get_pad_format(sensor, fh, fmt->which);
	mutex_unlock(&sensor->lock);

	return 0;
}

static int mt9m032_set_pad_format(struct v4l2_subdev *subdev,
				  struct v4l2_subdev_fh *fh,
				  struct v4l2_subdev_format *fmt)
{
	struct mt9m032 *sensor = to_mt9m032(subdev);
	int ret;

	mutex_lock(&sensor->lock);

	if (sensor->streaming && fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
		ret = -EBUSY;
		goto done;
	}

	/* Scaling is not supported, the format is thus fixed. */
	fmt->format = *__mt9m032_get_pad_format(sensor, fh, fmt->which);
	ret = 0;

done:
	mutex_unlock(&sensor->lock);
	return ret;
}

static int mt9m032_get_pad_crop(struct v4l2_subdev *subdev,
				struct v4l2_subdev_fh *fh,
				struct v4l2_subdev_crop *crop)
{
	struct mt9m032 *sensor = to_mt9m032(subdev);

	mutex_lock(&sensor->lock);
	crop->rect = *__mt9m032_get_pad_crop(sensor, fh, crop->which);
	mutex_unlock(&sensor->lock);

	return 0;
}

static int mt9m032_set_pad_crop(struct v4l2_subdev *subdev,
				struct v4l2_subdev_fh *fh,
				struct v4l2_subdev_crop *crop)
{
	struct mt9m032 *sensor = to_mt9m032(subdev);
	struct v4l2_mbus_framefmt *format;
	struct v4l2_rect *__crop;
	struct v4l2_rect rect;
	int ret = 0;

	mutex_lock(&sensor->lock);

	if (sensor->streaming && crop->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
		ret = -EBUSY;
		goto done;
	}

	/* Clamp the crop rectangle boundaries and align them to a multiple of 2
	 * pixels to ensure a GRBG Bayer pattern.
	 */
	rect.left = clamp(ALIGN(crop->rect.left, 2), MT9M032_COLUMN_START_MIN,
			  MT9M032_COLUMN_START_MAX);
	rect.top = clamp(ALIGN(crop->rect.top, 2), MT9M032_ROW_START_MIN,
			 MT9M032_ROW_START_MAX);
	rect.width = clamp_t(unsigned int, ALIGN(crop->rect.width, 2),
			     MT9M032_COLUMN_SIZE_MIN, MT9M032_COLUMN_SIZE_MAX);
	rect.height = clamp_t(unsigned int, ALIGN(crop->rect.height, 2),
			      MT9M032_ROW_SIZE_MIN, MT9M032_ROW_SIZE_MAX);

	rect.width = min_t(unsigned int, rect.width,
			   MT9M032_PIXEL_ARRAY_WIDTH - rect.left);
	rect.height = min_t(unsigned int, rect.height,
			    MT9M032_PIXEL_ARRAY_HEIGHT - rect.top);

	__crop = __mt9m032_get_pad_crop(sensor, fh, crop->which);

	if (rect.width != __crop->width || rect.height != __crop->height) {
		/* Reset the output image size if the crop rectangle size has
		 * been modified.
		 */
		format = __mt9m032_get_pad_format(sensor, fh, crop->which);
		format->width = rect.width;
		format->height = rect.height;
	}

	*__crop = rect;
	crop->rect = rect;

	if (crop->which == V4L2_SUBDEV_FORMAT_ACTIVE)
		ret = mt9m032_update_geom_timing(sensor);

done:
	mutex_unlock(&sensor->lock);
	return ret;
}

static int mt9m032_get_frame_interval(struct v4l2_subdev *subdev,
				      struct v4l2_subdev_frame_interval *fi)
{
	struct mt9m032 *sensor = to_mt9m032(subdev);

	mutex_lock(&sensor->lock);
	memset(fi, 0, sizeof(*fi));
	fi->interval = sensor->frame_interval;
	mutex_unlock(&sensor->lock);

	return 0;
}

static int mt9m032_set_frame_interval(struct v4l2_subdev *subdev,
				      struct v4l2_subdev_frame_interval *fi)
{
	struct mt9m032 *sensor = to_mt9m032(subdev);
	int ret;

	mutex_lock(&sensor->lock);

	if (sensor->streaming) {
		ret = -EBUSY;
		goto done;
	}

	/* Avoid divisions by 0. */
	if (fi->interval.denominator == 0)
		fi->interval.denominator = 1;

	ret = mt9m032_update_timing(sensor, &fi->interval);
	if (!ret)
		sensor->frame_interval = fi->interval;

done:
	mutex_unlock(&sensor->lock);
	return ret;
}

static int mt9m032_s_stream(struct v4l2_subdev *subdev, int streaming)
{
	struct mt9m032 *sensor = to_mt9m032(subdev);
	int ret;

	mutex_lock(&sensor->lock);
	ret = update_formatter2(sensor, streaming);
	if (!ret)
		sensor->streaming = streaming;
	mutex_unlock(&sensor->lock);

	return ret;
}

/* -----------------------------------------------------------------------------
 * V4L2 subdev core operations
 */

#ifdef CPTCFG_VIDEO_ADV_DEBUG
static int mt9m032_g_register(struct v4l2_subdev *sd,
			      struct v4l2_dbg_register *reg)
{
	struct mt9m032 *sensor = to_mt9m032(sd);
	struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
	int val;

	if (reg->reg > 0xff)
		return -EINVAL;

	val = mt9m032_read(client, reg->reg);
	if (val < 0)
		return -EIO;

	reg->size = 2;
	reg->val = val;

	return 0;
}

static int mt9m032_s_register(struct v4l2_subdev *sd,
			      const struct v4l2_dbg_register *reg)
{
	struct mt9m032 *sensor = to_mt9m032(sd);
	struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);

	if (reg->reg > 0xff)
		return -EINVAL;

	return mt9m032_write(client, reg->reg, reg->val);
}
#endif

/* -----------------------------------------------------------------------------
 * V4L2 subdev control operations
 */

static int update_read_mode2(struct mt9m032 *sensor, bool vflip, bool hflip)
{
	struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
	int reg_val = (vflip << MT9M032_READ_MODE2_VFLIP_SHIFT)
		    | (hflip << MT9M032_READ_MODE2_HFLIP_SHIFT)
		    | MT9M032_READ_MODE2_ROW_BLC
		    | 0x0007;

	return mt9m032_write(client, MT9M032_READ_MODE2, reg_val);
}

static int mt9m032_set_gain(struct mt9m032 *sensor, s32 val)
{
	struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
	int digital_gain_val;	/* in 1/8th (0..127) */
	int analog_mul;		/* 0 or 1 */
	int analog_gain_val;	/* in 1/16th. (0..63) */
	u16 reg_val;

	digital_gain_val = 51; /* from setup example */

	if (val < 63) {
		analog_mul = 0;
		analog_gain_val = val;
	} else {
		analog_mul = 1;
		analog_gain_val = val / 2;
	}

	/* a_gain = (1 + analog_mul) + (analog_gain_val + 1) / 16 */
	/* overall_gain = a_gain * (1 + digital_gain_val / 8) */

	reg_val = ((digital_gain_val & MT9M032_GAIN_DIGITAL_MASK)
		   << MT9M032_GAIN_DIGITAL_SHIFT)
		| ((analog_mul & 1) << MT9M032_GAIN_AMUL_SHIFT)
		| (analog_gain_val & MT9M032_GAIN_ANALOG_MASK);

	return mt9m032_write(client, MT9M032_GAIN_ALL, reg_val);
}

static int mt9m032_try_ctrl(struct v4l2_ctrl *ctrl)
{
	if (ctrl->id == V4L2_CID_GAIN && ctrl->val >= 63) {
		/* round because of multiplier used for values >= 63 */
		ctrl->val &= ~1;
	}

	return 0;
}

static int mt9m032_set_ctrl(struct v4l2_ctrl *ctrl)
{
	struct mt9m032 *sensor =
		container_of(ctrl->handler, struct mt9m032, ctrls);
	struct i2c_client *client = v4l2_get_subdevdata(&sensor->subdev);
	int ret;

	switch (ctrl->id) {
	case V4L2_CID_GAIN:
		return mt9m032_set_gain(sensor, ctrl->val);

	case V4L2_CID_HFLIP:
	/* case V4L2_CID_VFLIP: -- In the same cluster */
		return update_read_mode2(sensor, sensor->vflip->val,
					 sensor->hflip->val);

	case V4L2_CID_EXPOSURE:
		ret = mt9m032_write(client, MT9M032_SHUTTER_WIDTH_HIGH,
				    (ctrl->val >> 16) & 0xffff);
		if (ret < 0)
			return ret;

		return mt9m032_write(client, MT9M032_SHUTTER_WIDTH_LOW,
				     ctrl->val & 0xffff);
	}

	return 0;
}

static struct v4l2_ctrl_ops mt9m032_ctrl_ops = {
	.s_ctrl = mt9m032_set_ctrl,
	.try_ctrl = mt9m032_try_ctrl,
};

/* -------------------------------------------------------------------------- */

static const struct v4l2_subdev_core_ops mt9m032_core_ops = {
#ifdef CPTCFG_VIDEO_ADV_DEBUG
	.g_register = mt9m032_g_register,
	.s_register = mt9m032_s_register,
#endif
};

static const struct v4l2_subdev_video_ops mt9m032_video_ops = {
	.s_stream = mt9m032_s_stream,
	.g_frame_interval = mt9m032_get_frame_interval,
	.s_frame_interval = mt9m032_set_frame_interval,
};

static const struct v4l2_subdev_pad_ops mt9m032_pad_ops = {
	.enum_mbus_code = mt9m032_enum_mbus_code,
	.enum_frame_size = mt9m032_enum_frame_size,
	.get_fmt = mt9m032_get_pad_format,
	.set_fmt = mt9m032_set_pad_format,
	.set_crop = mt9m032_set_pad_crop,
	.get_crop = mt9m032_get_pad_crop,
};

static const struct v4l2_subdev_ops mt9m032_ops = {
	.core = &mt9m032_core_ops,
	.video = &mt9m032_video_ops,
	.pad = &mt9m032_pad_ops,
};

/* -----------------------------------------------------------------------------
 * Driver initialization and probing
 */

static int mt9m032_probe(struct i2c_client *client,
			 const struct i2c_device_id *devid)
{
	struct mt9m032_platform_data *pdata = client->dev.platform_data;
	struct i2c_adapter *adapter = client->adapter;
	struct mt9m032 *sensor;
	int chip_version;
	int ret;

	if (pdata == NULL) {
		dev_err(&client->dev, "No platform data\n");
		return -EINVAL;
	}

	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
		dev_warn(&client->dev,
			 "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n");
		return -EIO;
	}

	if (!client->dev.platform_data)
		return -ENODEV;

	sensor = devm_kzalloc(&client->dev, sizeof(*sensor), GFP_KERNEL);
	if (sensor == NULL)
		return -ENOMEM;

	mutex_init(&sensor->lock);

	sensor->pdata = pdata;

	v4l2_i2c_subdev_init(&sensor->subdev, client, &mt9m032_ops);
	sensor->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;

	chip_version = mt9m032_read(client, MT9M032_CHIP_VERSION);
	if (chip_version != MT9M032_CHIP_VERSION_VALUE) {
		dev_err(&client->dev, "MT9M032 not detected, wrong version "
			"0x%04x\n", chip_version);
		ret = -ENODEV;
		goto error_sensor;
	}

	dev_info(&client->dev, "MT9M032 detected at address 0x%02x\n",
		 client->addr);

	sensor->frame_interval.numerator = 1;
	sensor->frame_interval.denominator = 30;

	sensor->crop.left = MT9M032_COLUMN_START_DEF;
	sensor->crop.top = MT9M032_ROW_START_DEF;
	sensor->crop.width = MT9M032_COLUMN_SIZE_DEF;
	sensor->crop.height = MT9M032_ROW_SIZE_DEF;

	sensor->format.width = sensor->crop.width;
	sensor->format.height = sensor->crop.height;
	sensor->format.code = V4L2_MBUS_FMT_Y8_1X8;
	sensor->format.field = V4L2_FIELD_NONE;
	sensor->format.colorspace = V4L2_COLORSPACE_SRGB;

	v4l2_ctrl_handler_init(&sensor->ctrls, 5);

	v4l2_ctrl_new_std(&sensor->ctrls, &mt9m032_ctrl_ops,
			  V4L2_CID_GAIN, 0, 127, 1, 64);

	sensor->hflip = v4l2_ctrl_new_std(&sensor->ctrls,
					  &mt9m032_ctrl_ops,
					  V4L2_CID_HFLIP, 0, 1, 1, 0);
	sensor->vflip = v4l2_ctrl_new_std(&sensor->ctrls,
					  &mt9m032_ctrl_ops,
					  V4L2_CID_VFLIP, 0, 1, 1, 0);

	v4l2_ctrl_new_std(&sensor->ctrls, &mt9m032_ctrl_ops,
			  V4L2_CID_EXPOSURE, MT9M032_SHUTTER_WIDTH_MIN,
			  MT9M032_SHUTTER_WIDTH_MAX, 1,
			  MT9M032_SHUTTER_WIDTH_DEF);
	v4l2_ctrl_new_std(&sensor->ctrls, &mt9m032_ctrl_ops,
			  V4L2_CID_PIXEL_RATE, pdata->pix_clock,
			  pdata->pix_clock, 1, pdata->pix_clock);

	if (sensor->ctrls.error) {
		ret = sensor->ctrls.error;
		dev_err(&client->dev, "control initialization error %d\n", ret);
		goto error_ctrl;
	}

	v4l2_ctrl_cluster(2, &sensor->hflip);

	sensor->subdev.ctrl_handler = &sensor->ctrls;
	sensor->pad.flags = MEDIA_PAD_FL_SOURCE;
	ret = media_entity_init(&sensor->subdev.entity, 1, &sensor->pad, 0);
	if (ret < 0)
		goto error_ctrl;

	ret = mt9m032_write(client, MT9M032_RESET, 1);	/* reset on */
	if (ret < 0)
		goto error_entity;
	ret = mt9m032_write(client, MT9M032_RESET, 0);	/* reset off */
	if (ret < 0)
		goto error_entity;

	ret = mt9m032_setup_pll(sensor);
	if (ret < 0)
		goto error_entity;
	usleep_range(10000, 11000);

	ret = v4l2_ctrl_handler_setup(&sensor->ctrls);
	if (ret < 0)
		goto error_entity;

	/* SIZE */
	ret = mt9m032_update_geom_timing(sensor);
	if (ret < 0)
		goto error_entity;

	ret = mt9m032_write(client, 0x41, 0x0000);	/* reserved !!! */
	if (ret < 0)
		goto error_entity;
	ret = mt9m032_write(client, 0x42, 0x0003);	/* reserved !!! */
	if (ret < 0)
		goto error_entity;
	ret = mt9m032_write(client, 0x43, 0x0003);	/* reserved !!! */
	if (ret < 0)
		goto error_entity;
	ret = mt9m032_write(client, 0x7f, 0x0000);	/* reserved !!! */
	if (ret < 0)
		goto error_entity;
	if (sensor->pdata->invert_pixclock) {
		ret = mt9m032_write(client, MT9M032_PIX_CLK_CTRL,
				    MT9M032_PIX_CLK_CTRL_INV_PIXCLK);
		if (ret < 0)
			goto error_entity;
	}

	ret = mt9m032_write(client, MT9M032_RESTART, 1); /* Restart on */
	if (ret < 0)
		goto error_entity;
	msleep(100);
	ret = mt9m032_write(client, MT9M032_RESTART, 0); /* Restart off */
	if (ret < 0)
		goto error_entity;
	msleep(100);
	ret = update_formatter2(sensor, false);
	if (ret < 0)
		goto error_entity;

	return ret;

error_entity:
	media_entity_cleanup(&sensor->subdev.entity);
error_ctrl:
	v4l2_ctrl_handler_free(&sensor->ctrls);
error_sensor:
	mutex_destroy(&sensor->lock);
	return ret;
}

static int mt9m032_remove(struct i2c_client *client)
{
	struct v4l2_subdev *subdev = i2c_get_clientdata(client);
	struct mt9m032 *sensor = to_mt9m032(subdev);

	v4l2_device_unregister_subdev(subdev);
	v4l2_ctrl_handler_free(&sensor->ctrls);
	media_entity_cleanup(&subdev->entity);
	mutex_destroy(&sensor->lock);
	return 0;
}

static const struct i2c_device_id mt9m032_id_table[] = {
	{ MT9M032_NAME, 0 },
	{ }
};

MODULE_DEVICE_TABLE(i2c, mt9m032_id_table);

static struct i2c_driver mt9m032_i2c_driver = {
	.driver = {
		.name = MT9M032_NAME,
	},
	.probe = mt9m032_probe,
	.remove = mt9m032_remove,
	.id_table = mt9m032_id_table,
};
static int
msm_i2c_recover_bus_busy(struct msm_i2c_dev *dev)
{
	int i;
	uint32_t status = readl(dev->base + I2C_STATUS);
	int gpio_clk, gpio_dat;
	bool gpio_clk_status = false;

	if (!(status & (I2C_STATUS_BUS_ACTIVE | I2C_STATUS_WR_BUFFER_FULL)))
		return 0;

	msm_set_i2c_mux(true, &gpio_clk, &gpio_dat, 0, 0);

	if (status & I2C_STATUS_RD_BUFFER_FULL) {
		dev_warn(dev->dev, "Read buffer full, status %x, intf %x\n",
			 status, readl(dev->base + I2C_INTERFACE_SELECT));
		writel(I2C_WRITE_DATA_LAST_BYTE, dev->base + I2C_WRITE_DATA);
		readl(dev->base + I2C_READ_DATA);
	}
	else if (status & I2C_STATUS_BUS_MASTER) {
		dev_warn(dev->dev, "Still the bus master, status %x, intf %x\n",
			 status, readl(dev->base + I2C_INTERFACE_SELECT));
		writel(I2C_WRITE_DATA_LAST_BYTE | 0xff,
		       dev->base + I2C_WRITE_DATA);
	}

	dev_warn(dev->dev, "i2c_scl: %d, i2c_sda: %d\n",
		 gpio_get_value(gpio_clk), gpio_get_value(gpio_dat));

	for (i = 0; i < 9; i++) {
		if (gpio_get_value(gpio_dat) && gpio_clk_status)
			break;
		gpio_direction_output(gpio_clk, 0);
		udelay(5);
		gpio_direction_output(gpio_dat, 0);
		udelay(5);
		gpio_direction_input(gpio_clk);
		udelay(5);
		if (!gpio_get_value(gpio_clk))
			usleep_range(20, 30);
		if (!gpio_get_value(gpio_clk))
			msleep(10);
		gpio_clk_status = gpio_get_value(gpio_clk);
		gpio_direction_input(gpio_dat);
		udelay(5);
	}
	msm_set_i2c_mux(false, NULL, NULL,
		dev->clk_drv_str, dev->dat_drv_str);

	udelay(10);

	status = readl(dev->base + I2C_STATUS);
	if (!(status & I2C_STATUS_BUS_ACTIVE)) {
		dev_info(dev->dev, "Bus busy cleared after %d clock cycles, "
			 "status %x, intf %x\n",
			 i, status, readl(dev->base + I2C_INTERFACE_SELECT));
		return 0;
	}

	dev_warn(dev->dev, "Bus still busy, status %x, intf %x\n",
		 status, readl(dev->base + I2C_INTERFACE_SELECT));
	return -EBUSY;
}
static int epm_adc_gpio_configure_expander_enable(void)
{
	int rc = 0;

	if (epm_adc_first_request) {
		rc = gpio_request(GPIO_EPM_GLOBAL_ENABLE, "EPM_GLOBAL_EN");
		if (!rc) {
			gpio_direction_output(GPIO_EPM_GLOBAL_ENABLE, 1);
		} else {
			pr_err("%s: Configure EPM_GLOBAL_EN Failed\n",
								__func__);
			return rc;
		}
	} else {
		epm_adc_first_request = true;
	}

	usleep_range(EPM_ADC_CONVERSION_TIME_MIN,
			EPM_ADC_CONVERSION_TIME_MAX);

	rc = gpio_request(GPIO_PWR_MON_ENABLE, "GPIO_PWR_MON_ENABLE");
	if (!rc) {
		rc = gpio_direction_output(GPIO_PWR_MON_ENABLE, 1);
		if (rc) {
			pr_err("%s: Set GPIO_PWR_MON_ENABLE failed\n",
					__func__);
			return rc;
		}
	} else {
		pr_err("%s: gpio_request GPIO_PWR_MON_ENABLE failed\n",
				__func__);
		return rc;
	}

	rc = gpio_request(GPIO_ADC1_PWDN_N, "GPIO_ADC1_PWDN_N");
	if (!rc) {
		rc = gpio_direction_output(GPIO_ADC1_PWDN_N, 1);
		if (rc) {
			pr_err("%s: Set GPIO_ADC1_PWDN_N failed\n", __func__);
			return rc;
		}
	} else {
		pr_err("%s: gpio_request GPIO_ADC1_PWDN_N failed\n", __func__);
		return rc;
	}

	rc = gpio_request(GPIO_ADC2_PWDN_N, "GPIO_ADC2_PWDN_N");
	if (!rc) {
		rc = gpio_direction_output(GPIO_ADC2_PWDN_N, 1);
		if (rc) {
			pr_err("%s: Set GPIO_ADC2_PWDN_N failed\n",
					__func__);
			return rc;
		}
	} else {
		pr_err("%s: gpio_request GPIO_ADC2_PWDN_N failed\n",
				__func__);
		return rc;
	}

	rc = gpio_request(GPIO_EPM_SPI_ADC1_CS_N, "GPIO_EPM_SPI_ADC1_CS_N");
	if (!rc) {
		rc = gpio_direction_output(GPIO_EPM_SPI_ADC1_CS_N, 1);
		if (rc) {
			pr_err("%s:Set GPIO_EPM_SPI_ADC1_CS_N failed\n",
					__func__);
			return rc;
		}
	} else {
		pr_err("%s: gpio_request GPIO_EPM_SPI_ADC1_CS_N failed\n",
				__func__);
		return rc;
	}

	rc = gpio_request(GPIO_EPM_SPI_ADC2_CS_N,
			"GPIO_EPM_SPI_ADC2_CS_N");
	if (!rc) {
		rc = gpio_direction_output(GPIO_EPM_SPI_ADC2_CS_N, 1);
		if (rc) {
			pr_err("Set GPIO_EPM_SPI_ADC2_CS_N failed\n");
			return rc;
		}
	} else {
		pr_err("gpio_request GPIO_EPM_SPI_ADC2_CS_N failed\n");
		return rc;
	}

	rc = gpio_direction_output(GPIO_EPM_SPI_ADC1_CS_N, 0);
	if (rc) {
		pr_err("%s:Reset GPIO_EPM_SPI_ADC1_CS_N failed\n", __func__);
		return rc;
	}

	rc = gpio_direction_output(GPIO_EPM_SPI_ADC1_CS_N, 1);
	if (rc) {
		pr_err("%s: Set GPIO_EPM_SPI_ADC1_CS_N failed\n", __func__);
		return rc;
	}

	rc = gpio_request(GPIO_PWR_MON_START, "GPIO_PWR_MON_START");
	if (!rc) {
		rc = gpio_direction_output(GPIO_PWR_MON_START, 0);
		if (rc) {
			pr_err("%s: Reset GPIO_PWR_MON_START failed\n",
					__func__);
			return rc;
		}
	} else {
		pr_err("%s: gpio_request GPIO_PWR_MON_START failed\n",
				__func__);
		return rc;
	}

	rc = gpio_request(GPIO_PWR_MON_RESET_N, "GPIO_PWR_MON_RESET_N");
	if (!rc) {
		rc = gpio_direction_output(GPIO_PWR_MON_RESET_N, 0);
		if (rc) {
			pr_err("%s: Reset GPIO_PWR_MON_RESET_N failed\n",
					__func__);
			return rc;
		}
	} else {
		pr_err("%s: gpio_request GPIO_PWR_MON_RESET_N failed\n",
				__func__);
		return rc;
	}

	rc = gpio_direction_output(GPIO_PWR_MON_RESET_N, 1);
	if (rc) {
		pr_err("%s: Set GPIO_PWR_MON_RESET_N failed\n", __func__);
		return rc;
	}

	rc = gpio_direction_output(GPIO_EPM_SPI_ADC1_CS_N, 0);
	if (rc) {
		pr_err("%s:Reset GPIO_EPM_SPI_ADC1_CS_N failed\n", __func__);
		return rc;
	}
	return rc;
}
static int dw_mci_1_8v_signal_voltage_switch(struct dw_mci_slot *slot)
{
	unsigned long loop_count = 0x100000;
	struct dw_mci *host = slot->host;
	int ret = -1;
	int intrs;

	/* disable interrupt upon voltage switch. handle interrupt here
	 * 	and DO NOT triggle irq */
	mci_writel(host, CTRL,
		   (mci_readl(host, CTRL) & ~SDMMC_CTRL_INT_ENABLE));

	/* stop clock */
	mci_writel(host, CLKENA, (0x0 << 0));
	mci_writel(host, CMD, SDMMC_CMD_ONLY_CLK | SDMMC_VOLT_SWITCH);
	do {
		if (!(mci_readl(host, CMD) & SDMMC_CMD_START))
			break;
		loop_count--;
	} while (loop_count);

	if (!loop_count)
		dev_err(host->dev, " disable clock failed in voltage_switch\n");

	mmiowb();

	if (host->vqmmc) {
		ret = regulator_set_voltage(host->vqmmc, 1800000, 1800000);
		if (ret) {
			dev_warn(host->dev, "Switching to 1.8V signalling "
					    "voltage failed\n");
			return -EIO;
		}
	}

	/* Wait for 5ms */
	usleep_range(10000, 10500);

	ret = dw_mci_set_sel18(1);
	if (ret) {
		dev_err(host->dev, " dw_mci_set_sel18 error!\n");
		return ret;
	}

	/* start clock */
	mci_writel(host, CLKENA, (0x1 << 0));
	mci_writel(host, CMD, SDMMC_CMD_ONLY_CLK | SDMMC_VOLT_SWITCH);
	loop_count = 0x100000;
	do {
		if (!(mci_readl(host, CMD) & SDMMC_CMD_START))
			break;
		loop_count--;
	} while (loop_count);

	if (!loop_count)
		dev_err(host->dev, " enable clock failed in voltage_switch\n");

	/* poll cd interrupt */
	loop_count = 0x100000;
	do {
		intrs = mci_readl(host, RINTSTS);
		if (intrs & SDMMC_INT_CMD_DONE) {
			dev_err(host->dev, " cd 0x%x in voltage_switch\n",
				intrs);
			mci_writel(host, RINTSTS, intrs);
			break;
		}
		loop_count--;
	} while (loop_count);

	if (!loop_count)
		dev_err(host->dev, " poll cd failed in voltage_switch\n");

	/* enable interrupt */
	mci_writel(host, CTRL, (mci_readl(host, CTRL) | SDMMC_CTRL_INT_ENABLE));

	mmiowb();

	return ret;
}
Beispiel #19
0
int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us)
{
	struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf;
	struct bulk_cs_wrap *bcs = (struct bulk_cs_wrap *) us->iobuf;
	unsigned int transfer_length = scsi_bufflen(srb);
	unsigned int residue;
	int result;
	int fake_sense = 0;
	unsigned int cswlen;
	unsigned int cbwlen = US_BULK_CB_WRAP_LEN;

	/* Take care of BULK32 devices; set extra byte to 0 */
	if (unlikely(us->fflags & US_FL_BULK32)) {
		cbwlen = 32;
		us->iobuf[31] = 0;
	}

	/* set up the command wrapper */
	bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN);
	bcb->DataTransferLength = cpu_to_le32(transfer_length);
	bcb->Flags = srb->sc_data_direction == DMA_FROM_DEVICE ?
		US_BULK_FLAG_IN : 0;
	bcb->Tag = ++us->tag;
	bcb->Lun = srb->device->lun;
	if (us->fflags & US_FL_SCM_MULT_TARG)
		bcb->Lun |= srb->device->id << 4;
	bcb->Length = srb->cmd_len;

	/* copy the command payload */
	memset(bcb->CDB, 0, sizeof(bcb->CDB));
	memcpy(bcb->CDB, srb->cmnd, bcb->Length);

	/* send it to out endpoint */
	usb_stor_dbg(us, "Bulk Command S 0x%x T 0x%x L %d F %d Trg %d LUN %d CL %d\n",
		     le32_to_cpu(bcb->Signature), bcb->Tag,
		     le32_to_cpu(bcb->DataTransferLength), bcb->Flags,
		     (bcb->Lun >> 4), (bcb->Lun & 0x0F),
		     bcb->Length);
	result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
				bcb, cbwlen, NULL);
	usb_stor_dbg(us, "Bulk command transfer result=%d\n", result);
	if (result != USB_STOR_XFER_GOOD)
		return USB_STOR_TRANSPORT_ERROR;

	/* DATA STAGE */
	/* send/receive data payload, if there is any */

	/* Some USB-IDE converter chips need a 100us delay between the
	 * command phase and the data phase.  Some devices need a little
	 * more than that, probably because of clock rate inaccuracies. */
	if (unlikely(us->fflags & US_FL_GO_SLOW))
		usleep_range(125, 150);

	if (transfer_length) {
		unsigned int pipe = srb->sc_data_direction == DMA_FROM_DEVICE ? 
				us->recv_bulk_pipe : us->send_bulk_pipe;
		result = usb_stor_bulk_srb(us, pipe, srb);
		usb_stor_dbg(us, "Bulk data transfer result 0x%x\n", result);
		if (result == USB_STOR_XFER_ERROR)
			return USB_STOR_TRANSPORT_ERROR;

		/* If the device tried to send back more data than the
		 * amount requested, the spec requires us to transfer
		 * the CSW anyway.  Since there's no point retrying the
		 * the command, we'll return fake sense data indicating
		 * Illegal Request, Invalid Field in CDB.
		 */
		if (result == USB_STOR_XFER_LONG)
			fake_sense = 1;

		/*
		 * Sometimes a device will mistakenly skip the data phase
		 * and go directly to the status phase without sending a
		 * zero-length packet.  If we get a 13-byte response here,
		 * check whether it really is a CSW.
		 */
		if (result == USB_STOR_XFER_SHORT &&
				srb->sc_data_direction == DMA_FROM_DEVICE &&
				transfer_length - scsi_get_resid(srb) ==
					US_BULK_CS_WRAP_LEN) {
			struct scatterlist *sg = NULL;
			unsigned int offset = 0;

			if (usb_stor_access_xfer_buf((unsigned char *) bcs,
					US_BULK_CS_WRAP_LEN, srb, &sg,
					&offset, FROM_XFER_BUF) ==
						US_BULK_CS_WRAP_LEN &&
					bcs->Signature ==
						cpu_to_le32(US_BULK_CS_SIGN)) {
				usb_stor_dbg(us, "Device skipped data phase\n");
				scsi_set_resid(srb, transfer_length);
				goto skipped_data_phase;
			}
		}
	}

	/* See flow chart on pg 15 of the Bulk Only Transport spec for
	 * an explanation of how this code works.
	 */

	/* get CSW for device status */
	usb_stor_dbg(us, "Attempting to get CSW...\n");
	result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
				bcs, US_BULK_CS_WRAP_LEN, &cswlen);

	/* Some broken devices add unnecessary zero-length packets to the
	 * end of their data transfers.  Such packets show up as 0-length
	 * CSWs.  If we encounter such a thing, try to read the CSW again.
	 */
	if (result == USB_STOR_XFER_SHORT && cswlen == 0) {
		usb_stor_dbg(us, "Received 0-length CSW; retrying...\n");
		result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
				bcs, US_BULK_CS_WRAP_LEN, &cswlen);
	}

	/* did the attempt to read the CSW fail? */
	if (result == USB_STOR_XFER_STALLED) {

		/* get the status again */
		usb_stor_dbg(us, "Attempting to get CSW (2nd try)...\n");
		result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
				bcs, US_BULK_CS_WRAP_LEN, NULL);
	}

	/* if we still have a failure at this point, we're in trouble */
	usb_stor_dbg(us, "Bulk status result = %d\n", result);
	if (result != USB_STOR_XFER_GOOD)
		return USB_STOR_TRANSPORT_ERROR;

 skipped_data_phase:
	/* check bulk status */
	residue = le32_to_cpu(bcs->Residue);
	usb_stor_dbg(us, "Bulk Status S 0x%x T 0x%x R %u Stat 0x%x\n",
		     le32_to_cpu(bcs->Signature), bcs->Tag,
		     residue, bcs->Status);
	if (!(bcs->Tag == us->tag || (us->fflags & US_FL_BULK_IGNORE_TAG)) ||
		bcs->Status > US_BULK_STAT_PHASE) {
		usb_stor_dbg(us, "Bulk logical error\n");
		return USB_STOR_TRANSPORT_ERROR;
	}

	/* Some broken devices report odd signatures, so we do not check them
	 * for validity against the spec. We store the first one we see,
	 * and check subsequent transfers for validity against this signature.
	 */
	if (!us->bcs_signature) {
		us->bcs_signature = bcs->Signature;
		if (us->bcs_signature != cpu_to_le32(US_BULK_CS_SIGN))
			usb_stor_dbg(us, "Learnt BCS signature 0x%08X\n",
				     le32_to_cpu(us->bcs_signature));
	} else if (bcs->Signature != us->bcs_signature) {
		usb_stor_dbg(us, "Signature mismatch: got %08X, expecting %08X\n",
			     le32_to_cpu(bcs->Signature),
			     le32_to_cpu(us->bcs_signature));
		return USB_STOR_TRANSPORT_ERROR;
	}

	/* try to compute the actual residue, based on how much data
	 * was really transferred and what the device tells us */
	if (residue && !(us->fflags & US_FL_IGNORE_RESIDUE)) {

		/* Heuristically detect devices that generate bogus residues
		 * by seeing what happens with INQUIRY and READ CAPACITY
		 * commands.
		 */
		if (bcs->Status == US_BULK_STAT_OK &&
				scsi_get_resid(srb) == 0 &&
					((srb->cmnd[0] == INQUIRY &&
						transfer_length == 36) ||
					(srb->cmnd[0] == READ_CAPACITY &&
						transfer_length == 8))) {
			us->fflags |= US_FL_IGNORE_RESIDUE;

		} else {
			residue = min(residue, transfer_length);
			scsi_set_resid(srb, max(scsi_get_resid(srb),
			                                       (int) residue));
		}
	}

	/* based on the status code, we report good or bad */
	switch (bcs->Status) {
		case US_BULK_STAT_OK:
			/* device babbled -- return fake sense data */
			if (fake_sense) {
				memcpy(srb->sense_buffer, 
				       usb_stor_sense_invalidCDB, 
				       sizeof(usb_stor_sense_invalidCDB));
				return USB_STOR_TRANSPORT_NO_SENSE;
			}

			/* command good -- note that data could be short */
			return USB_STOR_TRANSPORT_GOOD;

		case US_BULK_STAT_FAIL:
			/* command failed */
			return USB_STOR_TRANSPORT_FAILED;

		case US_BULK_STAT_PHASE:
			/* phase error -- note that a transport reset will be
			 * invoked by the invoke_transport() function
			 */
			return USB_STOR_TRANSPORT_ERROR;
	}

	/* we should never get here, but if we do, we're in trouble */
	return USB_STOR_TRANSPORT_ERROR;
}
Beispiel #20
0
/******************************************************************************
 *    function:   smt113j_spi_thread_loop
 *    brief   :   
 *    date    :   
 *    author  :   
 *
 *    return  :   none
 *    input   :   none
 *    output  :   none
 ******************************************************************************/
static int smt113j_spi_thread_loop ( void  *arg )
{
	int ret = 0;
	unsigned char status = 0;
	
	DEBUG_PRINT("smt113j_spi_thread_loop : Start!");

	while ( !kthread_should_stop() ) 
	{
		DEBUG_PRINT("smt113j_spi_thread_loop : spi_work_thread->status[%d]!", 
					spi_work_thread->status );

		/* wait event */
		if ( SMT113J_SPI_SYNC_RUN != spi_work_thread->status )
		{
			DEBUG_PRINT("smt113j_spi_thread_loop : Thread Wait!");
			
	 		ret = wait_event_interruptible ( spi_work_thread->thread_wait, 
	 					SMT113J_SPI_SYNC_STOP != spi_work_thread->status );

			if ( 0 != ret )
			{
				DEBUG_PRINT ("Not Interruptible : No Case");
				continue;
			}
			
			DEBUG_PRINT(
				"smt113j_spi_thread_loop : Thread Run << status[%d] >>!", 
				spi_work_thread->status );
		}
		/*** SPI Sync ***/
		switch ( spi_work_thread->status )
		{
			/*** SPI Sync Command ***/
			case SMT113J_SPI_SYNC_RUN:
				
				mutex_lock(&smt1113j_spi_device_lock);
				if ( spi_work_thread->status == SMT113J_SPI_SYNC_RUN )
				{
				/*** TS Buffering Status ***/
				ret = smt113j_spi_cmd_bufstat ( &status );
				}
				mutex_unlock(&smt1113j_spi_device_lock);
				
				if ( 0 > ret )
				{
					ERROR_PRINT ("smt113j_spi_thread_loop : Pakcet Error = %d",
								 ret );
					continue;
				}
				
				/*** Pakcet state ( status = 0x00<not ready>/0x01<ready> ) ***/
				if ( 0x01 == ( status & 0x01 ))
				{
					DEBUG_PRINT (
						"smt113j_spi_thread_read() before : status[%d]", 
						spi_work_thread->status );

					mutex_lock(&smt1113j_spi_device_lock);
					if ( spi_work_thread->status == SMT113J_SPI_SYNC_RUN )
					{
					/*** Buffer Ready ***/
					smt113j_spi_thread_read();
					}
					mutex_unlock(&smt1113j_spi_device_lock);

					DEBUG_PRINT (
						"smt113j_spi_thread_read() after : status[%d]", 
						spi_work_thread->status );
				}
				else
				{
					DEBUG_PRINT ("smt113j_spi_thread_loop : Not Ready");
					
					/*** inside chip buffer is over or under run check ***/
					if ( 0 != ( status & 0x06 ))
					{
						/*** Over or Under Run ***/
						ERROR_PRINT (
							"smt113j_spi_thread_loop : buffer Error < %s >",
							((0x02 == (status & 0x02))?
							"Under-run":((0x04 == (status & 0x04))?
							"Over-run":"No Error")));
						smt113j_spi_cmd_pktsync();
					}
					else
					{
						DEBUG_PRINT (
							"smt113j_spi_thread_loop : Buffering Wait");
					}
					/* 20ms sleep */
					usleep_range (( 20 * 1000 ), ( 20 * 1000 ));
				}
				break;
			default:
				/*** Thread Status Error ***/
				ERROR_PRINT (
					"smt113j_spi_thread_loop : Thread Status Error : %d",
					spi_work_thread->status );
					spi_work_thread->status = SMT113J_SPI_SYNC_STOP;
				break;
		}
	}
	DEBUG_PRINT("smt113j_spi_thread_loop : End!");

	return ( 0 );
}
Beispiel #21
0
void ov5647_sunny_p5v02s_read_otp(struct msm_sensor_ctrl_t *s_ctrl,
		uint16_t index, struct otp_struct *potp)
{
	uint16_t temp, i;
	uint16_t address;
	/* read otp into buffer */
	msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 0x3d21, 0x01,
		MSM_CAMERA_I2C_BYTE_DATA);

	usleep_range(2000, 2500);
	address = 0x3d05 + index*9;

	msm_camera_i2c_read(s_ctrl->sensor_i2c_client, address, &temp,
		MSM_CAMERA_I2C_BYTE_DATA);

	potp->module_integrator_id = temp;
	potp->customer_id = temp & 0x7f;

	msm_camera_i2c_read(s_ctrl->sensor_i2c_client, (address+1), &temp,
		MSM_CAMERA_I2C_BYTE_DATA);
	potp->lens_id = temp;

	msm_camera_i2c_read(s_ctrl->sensor_i2c_client, (address+2), &temp,
		MSM_CAMERA_I2C_BYTE_DATA);
	potp->rg_ratio = temp;

	msm_camera_i2c_read(s_ctrl->sensor_i2c_client, (address+3), &temp,
		MSM_CAMERA_I2C_BYTE_DATA);
	potp->bg_ratio = temp;

	msm_camera_i2c_read(s_ctrl->sensor_i2c_client, (address+4), &temp,
		MSM_CAMERA_I2C_BYTE_DATA);
	potp->user_data[0] = temp;

	msm_camera_i2c_read(s_ctrl->sensor_i2c_client, (address+5), &temp,
		MSM_CAMERA_I2C_BYTE_DATA);
	potp->user_data[1] = temp;

	msm_camera_i2c_read(s_ctrl->sensor_i2c_client, (address+6), &temp,
		MSM_CAMERA_I2C_BYTE_DATA);
	potp->user_data[2] = temp;

	msm_camera_i2c_read(s_ctrl->sensor_i2c_client, (address+7), &temp,
		MSM_CAMERA_I2C_BYTE_DATA);
	potp->user_data[3] = temp;

	msm_camera_i2c_read(s_ctrl->sensor_i2c_client, (address+8), &temp,
		MSM_CAMERA_I2C_BYTE_DATA);
	potp->user_data[4] = temp;

	CDBG("%s customer_id  = 0x%02x\r\n", __func__, potp->customer_id);
	CDBG("%s lens_id      = 0x%02x\r\n", __func__, potp->lens_id);
	CDBG("%s rg_ratio     = 0x%02x\r\n", __func__, potp->rg_ratio);
	CDBG("%s bg_ratio     = 0x%02x\r\n", __func__, potp->bg_ratio);
	CDBG("%s user_data[0] = 0x%02x\r\n", __func__, potp->user_data[0]);
	CDBG("%s user_data[1] = 0x%02x\r\n", __func__, potp->user_data[1]);
	CDBG("%s user_data[2] = 0x%02x\r\n", __func__, potp->user_data[2]);
	CDBG("%s user_data[3] = 0x%02x\r\n", __func__, potp->user_data[3]);
	CDBG("%s user_data[4] = 0x%02x\r\n", __func__, potp->user_data[4]);

	/* disable otp read */
	msm_camera_i2c_write(s_ctrl->sensor_i2c_client, 0x3d21, 0x00,
		MSM_CAMERA_I2C_BYTE_DATA);
	/* clear otp buffer */
	for (i = 0; i < 32; i++) {
		msm_camera_i2c_write(s_ctrl->sensor_i2c_client, (0x3d00+i),
				0x00, MSM_CAMERA_I2C_BYTE_DATA);
	}
}
/* sysfs store function for ramp */
static ssize_t qpnp_wled_ramp_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t count)
{
	struct qpnp_wled *wled = dev_get_drvdata(dev);
	int i, rc;

	mutex_lock(&wled->lock);

	if (!wled->cdev.brightness) {
		rc = qpnp_wled_module_en(wled, wled->ctrl_base, true);
		if (rc) {
			dev_err(&wled->spmi->dev, "wled enable failed\n");
			goto unlock_mutex;
		}
	}

	/* ramp up */
	for (i = 0; i <= wled->cdev.max_brightness;) {
		rc = qpnp_wled_set_level(wled, i);
		if (rc) {
			dev_err(&wled->spmi->dev, "wled set level failed\n");
			goto restore_brightness;
		}

		if (wled->ramp_ms < QPNP_WLED_MIN_MSLEEP)
			usleep_range(wled->ramp_ms * USEC_PER_MSEC,
					wled->ramp_ms * USEC_PER_MSEC);
		else
			msleep(wled->ramp_ms);

		if (i == wled->cdev.max_brightness)
			break;

		i += wled->ramp_step;
		if (i > wled->cdev.max_brightness)
			i = wled->cdev.max_brightness;
	}

	/* ramp down */
	for (i = wled->cdev.max_brightness; i >= 0;) {
		rc = qpnp_wled_set_level(wled, i);
		if (rc) {
			dev_err(&wled->spmi->dev, "wled set level failed\n");
			goto restore_brightness;
		}

		if (wled->ramp_ms < QPNP_WLED_MIN_MSLEEP)
			usleep_range(wled->ramp_ms * USEC_PER_MSEC,
					wled->ramp_ms * USEC_PER_MSEC);
		else
			msleep(wled->ramp_ms);

		if (i == 0)
			break;

		i -= wled->ramp_step;
		if (i < 0)
			i = 0;
	}

	dev_info(&wled->spmi->dev, "wled ramp complete\n");

restore_brightness:
	/* restore the old brightness */
	qpnp_wled_set_level(wled, wled->cdev.brightness);
	if (!wled->cdev.brightness) {
		rc = qpnp_wled_module_en(wled, wled->ctrl_base, false);
		if (rc)
			dev_err(&wled->spmi->dev, "wled enable failed\n");
	}
unlock_mutex:
	mutex_unlock(&wled->lock);

	return count;
}
Beispiel #23
0
static int dwc3_otg_start_host(struct usb_otg *otg, int on)
{
	struct dwc3_otg *dotg = container_of(otg, struct dwc3_otg, otg);
	struct dwc3_ext_xceiv *ext_xceiv = dotg->ext_xceiv;
	struct dwc3 *dwc = dotg->dwc;
	int ret = 0;
#ifdef CONFIG_PANTECH_QUALCOMM_OTG_MODE_OVP_BUG
	//xsemiyas_debug
	int value;
#endif
#if defined(CONFIG_PANTECH_USB_SMB_OTG_DISABLE_LOW_BATTERY) || defined(CONFIG_PANTECH_USB_TI_OTG_DISABLE_LOW_BATTERY)
	int level;
#endif
	if (!dwc->xhci)
		return -EINVAL;

#ifdef FEATURE_PANTECH_USB_CHARGER_INIT_ERROR
	if(!charger_ready_status())
		return -ENODEV;
#endif
#if !defined(CONFIG_PANTECH_PMIC_CHARGER_SMB347) && !defined(CONFIG_PANTECH_PMIC_CHARGER_SMB349) && !defined(CONFIG_PANTECH_PMIC_CHARGER_BQ2419X)
	if (!dotg->vbus_otg) {
		dotg->vbus_otg = devm_regulator_get(dwc->dev->parent,
							"vbus_dwc3");
		if (IS_ERR(dotg->vbus_otg)) {
			dev_err(dwc->dev, "Failed to get vbus regulator\n");
			ret = PTR_ERR(dotg->vbus_otg);
			dotg->vbus_otg = 0;
			return ret;
		}
	}
#endif /* !defined(CONFIG_PANTECH_PMIC_CHARGER_SMB347) && !defined(CONFIG_PANTECH_PMIC_CHARGER_SMB349) && !defined(CONFIG_PANTECH_CHARGER_BQ2419X) */
#if defined(CONFIG_PANTECH_USB_SMB_OTG_DISABLE_LOW_BATTERY) && defined(CONFIG_PANTECH_PMIC_OTG_UVLO)
	level = max17058_get_soc_for_otg();
#elif defined(CONFIG_PANTECH_USB_TI_OTG_DISABLE_LOW_BATTERY) && defined(CONFIG_PANTECH_EF63_PMIC_FUELGAUGE_MAX17058)
	level = max17058_get_soc_for_led();
#else
	level = 50;
#endif
	if (on) {
		dev_dbg(otg->phy->dev, "%s: turn on host\n", __func__);

#if defined(CONFIG_PANTECH_PMIC_CHARGER_SMB347) || defined(CONFIG_PANTECH_PMIC_CHARGER_SMB349)
		//xsemiyas_debug:warmup_time
		smb349_otg_power(1);
		usleep_range(60, 100);
#ifdef CONFIG_PANTECH_PMIC_OTG
		smb349_otg_power_current(3);
#endif /* CONFIG_PANTECH_PMIC_OTG */
		smb349_otg_power(0);
#endif /* defined(CONFIG_PANTECH_PMIC_CHARGER_SMB347) || defined(CONFIG_PANTECH_PMIC_CHARGER_SMB349) */

		/*
		 * This should be revisited for more testing post-silicon.
		 * In worst case we may need to disconnect the root hub
		 * before stopping the controller so that it does not
		 * interfere with runtime pm/system pm.
		 * We can also consider registering and unregistering xhci
		 * platform device. It is almost similar to add_hcd and
		 * remove_hcd, But we may not use standard set_host method
		 * anymore.
		 */
		dwc3_otg_set_hsphy_auto_suspend(dotg, true);
		dwc3_otg_set_host_regs(dotg);
		/*
		 * FIXME If micro A cable is disconnected during system suspend,
		 * xhci platform device will be removed before runtime pm is
		 * enabled for xhci device. Due to this, disable_depth becomes
		 * greater than one and runtimepm is not enabled for next microA
		 * connect. Fix this by calling pm_runtime_init for xhci device.
		 */
		pm_runtime_init(&dwc->xhci->dev);
		ret = platform_device_add(dwc->xhci);
		if (ret) {
			dev_err(otg->phy->dev,
				"%s: failed to add XHCI pdev ret=%d\n",
				__func__, ret);
			return ret;
		}

		dwc3_otg_notify_host_mode(otg, on);
#ifdef CONFIG_PANTECH_QUALCOMM_OTG_MODE_OVP_BUG		
		//xsemiyas_debug
		while((value = get_pantech_chg_otg_mode()) != 1){
			if(value == -1){
				set_pantech_chg_otg_mode(0);
				dev_err(otg->phy->dev, "unable to enable qpnp_otg_mode\n");
				return -ENXIO;
			}
			msleep(10);
		}
#endif

#if defined(CONFIG_PANTECH_USB_SMB_OTG_DISABLE_LOW_BATTERY)
		if (level < 10) {
			dev_err(dwc->dev, "Low Battery!!, OTG power not set!\n");
#ifdef CONFIG_ANDROID_PANTECH_USB_OTG_INTENT
			set_otg_dev_state(2);
#endif			
			return 0;
		}
#elif defined(CONFIG_PANTECH_USB_TI_OTG_DISABLE_LOW_BATTERY)
		if (level < 10) {
			dev_err(dwc->dev, "Battery is not enough!, OTG power remove!\n");
#ifdef CONFIG_ANDROID_PANTECH_USB_OTG_INTENT
			set_otg_dev_state(2);
#endif
#if defined(CONFIG_PANTECH_PMIC_CHARGER_BQ2419X)
			//chg_force_switching_scope(1); //otg power remove
			dwc3_otg_notify_host_mode(otg, 0); //otg power remove
#endif
			return 0;
		}
#endif

#ifdef CONFIG_PANTECH_USB_TUNE_SIGNALING_PARAM
		pantech_set_otg_signaling_param(on);
#endif
#if defined(CONFIG_PANTECH_PMIC_CHARGER_SMB347) || defined(CONFIG_PANTECH_PMIC_CHARGER_SMB349)
		smb349_otg_power(on);
#ifdef CONFIG_PANTECH_PMIC_OTG
		usleep_range(60, 100);//xsemiyas_debug: change 60uS
		smb349_otg_power_current(3); //750mA current setting
#endif /* CONFIG_PANTECH_PMIC_OTG */
#elif !defined(CONFIG_PANTECH_PMIC_CHARGER_BQ2419X)
		ret = regulator_enable(dotg->vbus_otg);
		if (ret) {
			dev_err(otg->phy->dev, "unable to enable vbus_otg\n");
			platform_device_del(dwc->xhci);
			return ret;
		}
#endif /* defined(CONFIG_PANTECH_PMIC_CHARGER_SMB347) || defined(CONFIG_PANTECH_PMIC_CHARGER_SMB349) */
		/* re-init OTG EVTEN register as XHCI reset clears it */
		if (ext_xceiv && !ext_xceiv->otg_capability)
			dwc3_otg_reset(dotg);
#if defined(CONFIG_PANTECH_USB_SMB_OTG_DISABLE_LOW_BATTERY) || defined(CONFIG_PANTECH_USB_TI_OTG_DISABLE_LOW_BATTERY)
		is_otg_enabled = 1;
#endif

	} else {
		dev_dbg(otg->phy->dev, "%s: turn off host\n", __func__);

#ifdef CONFIG_PANTECH_USB_SMB_OTG_DISABLE_LOW_BATTERY
		if (level >= 10) {
#endif
#if defined(CONFIG_PANTECH_PMIC_CHARGER_SMB347) || defined(CONFIG_PANTECH_PMIC_CHARGER_SMB349)
		smb349_otg_power(on);
#ifdef CONFIG_PANTECH_PMIC_OTG
		smb349_otg_power_current(1); //250mA current setting
#endif /* CONFIG_PANTECH_PMIC_OTG */
#ifdef CONFIG_PANTECH_USB_SMB_OTG_DISABLE_LOW_BATTERY
		}
#endif
#elif !defined(CONFIG_PANTECH_PMIC_CHARGER_BQ2419X)
		ret = regulator_disable(dotg->vbus_otg);
		if (ret) {
			dev_err(otg->phy->dev, "unable to disable vbus_otg\n");
			return ret;
		}
#endif /* defined(CONFIG_PANTECH_PMIC_CHARGER_SMB347) || defined(CONFIG_PANTECH_PMIC_CHARGER_SMB349) */
#ifdef CONFIG_PANTECH_USB_TUNE_SIGNALING_PARAM
		pantech_set_otg_signaling_param(on);
#endif
#if defined(CONFIG_PANTECH_USB_SMB_OTG_DISABLE_LOW_BATTERY) || defined(CONFIG_PANTECH_USB_TI_OTG_DISABLE_LOW_BATTERY)
		is_otg_enabled = 0;
#endif
		dwc3_otg_notify_host_mode(otg, on);

#ifdef CONFIG_PANTECH_SIO_BUG_FIX
		/* FIXME : Sometimes sm_work is executed twice in abnormal state.
		 * So platform_device_del is executed twice. 
		 * And this code is occurred NULL pointer exception at seconds procedure.
		 * We are fixed below code only executed one.
		 * from LS4-USB tarial
		 */
		if (dwc->xhci)
			platform_device_del(dwc->xhci);
#else
		platform_device_del(dwc->xhci);
#endif
		/*
		 * Perform USB hardware RESET (both core reset and DBM reset)
		 * when moving from host to peripheral. This is required for
		 * peripheral mode to work.
		 */
		if (ext_xceiv && ext_xceiv->otg_capability &&
						ext_xceiv->ext_block_reset)
			ext_xceiv->ext_block_reset(ext_xceiv, true);

		dwc3_otg_set_hsphy_auto_suspend(dotg, false);
		dwc3_otg_set_peripheral_regs(dotg);

		/* re-init core and OTG registers as block reset clears these */
		dwc3_post_host_reset_core_init(dwc);
		if (ext_xceiv && !ext_xceiv->otg_capability)
			dwc3_otg_reset(dotg);
	}

	return 0;
}
Beispiel #24
0
/*
 * Get hardware mutex to block firmware from accessing the pld.
 * It is possible for the firmware may hold the mutex for an extended length of
 * time. This function will block until access has been granted.
 */
static void kempld_get_hardware_mutex(struct kempld_device_data *pld)
{
	/* The mutex bit will read 1 until access has been granted */
	while (ioread8(pld->io_index) & KEMPLD_MUTEX_KEY)
		usleep_range(1000, 3000);
}
static int t4k35_power_ctrl(struct v4l2_subdev *sd, int flag)
{
	struct i2c_client *client = v4l2_get_subdevdata(sd);
	int ret = 0;
	int reset_gpio_pin, vcm_pd_gpio_pin;

	if (first_open) {
		camera_reset = -1;
		camera_power = -1;
		camera_vcm_pd = -1;
		camera_sensor_2_8v = -1;
		HW_ID = Read_HW_ID();
		first_open = false;
	}

	reset_gpio_pin = 177;
	vcm_pd_gpio_pin = 175;


	if (camera_reset < 0) {
		gpio_free(reset_gpio_pin);
		ret = camera_sensor_gpio(reset_gpio_pin, GP_CAMERA_0_RESET,
					GPIOF_DIR_OUT, 0);
		if (ret < 0) {
			pr_err("%s error\n", GP_CAMERA_0_RESET);
			return ret;
		}
		camera_reset = reset_gpio_pin;
	}
	
	if (camera_vcm_pd < 0) {
		ret = camera_sensor_gpio(vcm_pd_gpio_pin, GP_CAMERA_0_POWER_DOWN,
					GPIOF_DIR_OUT, 0);
		if (ret < 0) {
			pr_err("%s error\n", GP_CAMERA_0_POWER_DOWN);
			return ret;
		}
		camera_vcm_pd = reset_gpio_pin;
	}

	pr_info("[t4k35_platform] HW_ID = %d\n", HW_ID);
	if (camera_sensor_2_8v < 0 && HW_ID >= 3) { /*for PR HW change 2.8V*/
		ret = camera_sensor_gpio(-1, GP_CAMERA_1_2_8v,
				 GPIOF_DIR_OUT, 0);
		if (ret < 0) {
			pr_err("%s not available.\n", GP_CAMERA_1_2_8v);
			return ret;
		}
		camera_sensor_2_8v = GP_CORE_012;
	}
#if 0
	if (is_moorefield()) {
#ifdef CONFIG_INTEL_SCU_IPC_UTIL
		ret = intel_scu_ipc_msic_vprog1(flag);
		if (ret) {
			pr_err("t4k35 power failed\n");
			return ret;
		}
		ret = intel_scu_ipc_msic_vprog3(flag);
#else
		ret = -ENODEV;
#endif
		if (ret)
			pr_err("t4k35 power failed\n");
		if (flag)
			usleep_range(1000, 1200);

		return ret;
	}
#endif
	if (flag) {
		gpio_set_value(camera_reset, 0);
		usleep_range(200, 300);
		pr_info("%s camera_reset is low\n", __func__);
		/* turn on VCM power 2.85V */
		if (!camera_vemmc1_on) {
			camera_vemmc1_on = 1;
			ret = regulator_enable(vemmc1_reg);
			/* ret = regulator_enable(vemmc1_reg); */
			if (!ret) {
				pr_info("%s enable regulator vemmc1 2.85V\n", __func__);
			} else {
				pr_err("%s Failed to enable regulator vemmc1\n", __func__);
			return ret;
			}
		}
		if (!camera_vprog2_on) {
			camera_vprog2_on = 1;
			ret = regulator_enable(vprog2_reg);
			if (!ret) {
				pr_info("%s enable regulator vprog2 1.2V\n", __func__);
			} else {
				pr_err("%s Failed to enable regulator vprog2\n", __func__);
			return ret;
			}
		}
		if (!camera_vprog1_on) {
			camera_vprog1_on = 1;
			ret = regulator_enable(vprog1_reg);
			if (!ret) {
				pr_info("%s enable regulator vprog1 1.8V\n", __func__);
			} else {
				pr_err("%s Failed to enable regulator vprog1\n", __func__);
				return ret;
			}
		}
		if (camera_sensor_2_8v >= 0) {
			gpio_set_value(camera_sensor_2_8v, 1);
			pr_err("<<< 2.8v = 1\n");
		}
	} else {
		if (camera_sensor_2_8v >= 0) {
			gpio_set_value(camera_sensor_2_8v, 0);
			pr_err("<<< 2.8v = 0\n");
			gpio_free(camera_sensor_2_8v);
			camera_sensor_2_8v = -1;
		}

		if (camera_vprog1_on) {
			camera_vprog1_on = 0;
			ret = regulator_disable(vprog1_reg);
			if (!ret) {
				pr_info("%s disable regulator vprog1 1.8V\n", __func__);
			} else {
				pr_err("%s Failed to disable regulator vprog1\n", __func__);
			return ret;
			}
		}
		if (camera_vprog2_on) {
			camera_vprog2_on = 0;
			ret = regulator_disable(vprog2_reg);
			if (!ret) {
				pr_info("%s disable regulator vprog2 1.2V\n", __func__);
			} else {
				pr_err("%s Failed to disable regulator vprog2\n", __func__);
			return ret;
			}
		}
		/* turn off VCM power 2.85V */
		if (camera_vemmc1_on) {
			camera_vemmc1_on = 0;
			ret = regulator_disable(vemmc1_reg);
			if (!ret) {
				pr_info("%s disable regulator vemmc1 2.85V\n", __func__);
			} else {
				pr_err("%s Failed to disable regulator vemmc1\n", __func__);
			return ret;
			}
		}
	}
	return 0;
}
Beispiel #26
0
static int apds990x_probe(struct i2c_client *client,
				const struct i2c_device_id *id)
{
	struct apds990x_chip *chip;
	int err;

	chip = kzalloc(sizeof *chip, GFP_KERNEL);
	if (!chip)
		return -ENOMEM;

	i2c_set_clientdata(client, chip);
	chip->client  = client;

	init_waitqueue_head(&chip->wait);
	mutex_init(&chip->mutex);
	chip->pdata	= client->dev.platform_data;

	if (chip->pdata == NULL) {
		dev_err(&client->dev, "platform data is mandatory\n");
		err = -EINVAL;
		goto fail1;
	}

	if (chip->pdata->cf.ga == 0) {
		/* set uncovered sensor default parameters */
		chip->cf.ga = 1966; /* 0.48 * APDS_PARAM_SCALE */
		chip->cf.cf1 = 4096; /* 1.00 * APDS_PARAM_SCALE */
		chip->cf.irf1 = 9134; /* 2.23 * APDS_PARAM_SCALE */
		chip->cf.cf2 = 2867; /* 0.70 * APDS_PARAM_SCALE */
		chip->cf.irf2 = 5816; /* 1.42 * APDS_PARAM_SCALE */
		chip->cf.df = 52;
	} else {
		chip->cf = chip->pdata->cf;
	}

	/* precalculate inverse chip factors for threshold control */
	chip->rcf.afactor =
		(chip->cf.irf1 - chip->cf.irf2) * APDS_PARAM_SCALE /
		(chip->cf.cf1 - chip->cf.cf2);
	chip->rcf.cf1 = APDS_PARAM_SCALE * APDS_PARAM_SCALE /
		chip->cf.cf1;
	chip->rcf.irf1 = chip->cf.irf1 * APDS_PARAM_SCALE /
		chip->cf.cf1;
	chip->rcf.cf2 = APDS_PARAM_SCALE * APDS_PARAM_SCALE /
		chip->cf.cf2;
	chip->rcf.irf2 = chip->cf.irf2 * APDS_PARAM_SCALE /
		chip->cf.cf2;

	/* Set something to start with */
	chip->lux_thres_hi = APDS_LUX_DEF_THRES_HI;
	chip->lux_thres_lo = APDS_LUX_DEF_THRES_LO;
	chip->lux_calib = APDS_LUX_NEUTRAL_CALIB_VALUE;

	chip->prox_thres = APDS_PROX_DEF_THRES;
	chip->pdrive = chip->pdata->pdrive;
	chip->pdiode = APDS_PDIODE_IR;
	chip->pgain = APDS_PGAIN_1X;
	chip->prox_calib = APDS_PROX_NEUTRAL_CALIB_VALUE;
	chip->prox_persistence = APDS_DEFAULT_PROX_PERS;
	chip->prox_continuous_mode = false;

	chip->regs[0].supply = reg_vcc;
	chip->regs[1].supply = reg_vled;

	err = regulator_bulk_get(&client->dev,
				 ARRAY_SIZE(chip->regs), chip->regs);
	if (err < 0) {
		dev_err(&client->dev, "Cannot get regulators\n");
		goto fail1;
	}

	err = regulator_bulk_enable(ARRAY_SIZE(chip->regs), chip->regs);
	if (err < 0) {
		dev_err(&client->dev, "Cannot enable regulators\n");
		goto fail2;
	}

	usleep_range(APDS_STARTUP_DELAY, 2 * APDS_STARTUP_DELAY);

	err = apds990x_detect(chip);
	if (err < 0) {
		dev_err(&client->dev, "APDS990X not found\n");
		goto fail3;
	}

	pm_runtime_set_active(&client->dev);

	apds990x_configure(chip);
	apds990x_set_arate(chip, APDS_LUX_DEFAULT_RATE);
	apds990x_mode_on(chip);

	pm_runtime_enable(&client->dev);

	if (chip->pdata->setup_resources) {
		err = chip->pdata->setup_resources();
		if (err) {
			err = -EINVAL;
			goto fail3;
		}
	}

	err = sysfs_create_group(&chip->client->dev.kobj,
				apds990x_attribute_group);
	if (err < 0) {
		dev_err(&chip->client->dev, "Sysfs registration failed\n");
		goto fail4;
	}

	err = request_threaded_irq(client->irq, NULL,
				apds990x_irq,
				IRQF_TRIGGER_FALLING | IRQF_TRIGGER_LOW |
				IRQF_ONESHOT,
				"apds990x", chip);
	if (err) {
		dev_err(&client->dev, "could not get IRQ %d\n",
			client->irq);
		goto fail5;
	}
	return err;
fail5:
	sysfs_remove_group(&chip->client->dev.kobj,
			&apds990x_attribute_group[0]);
fail4:
	if (chip->pdata && chip->pdata->release_resources)
		chip->pdata->release_resources();
fail3:
	regulator_bulk_disable(ARRAY_SIZE(chip->regs), chip->regs);
fail2:
	regulator_bulk_free(ARRAY_SIZE(chip->regs), chip->regs);
fail1:
	kfree(chip);
	return err;
}
static void msm8960_ext_spk_power_amp_off(u32 spk)
{
	struct pm_gpio param = {
		.direction      = PM_GPIO_DIR_IN,
		.output_buffer  = PM_GPIO_OUT_BUF_CMOS,
		.pull      = PM_GPIO_PULL_NO,
		.vin_sel	= PM_GPIO_VIN_S4,
		.out_strength   = PM_GPIO_STRENGTH_MED,
		.function       = PM_GPIO_FUNC_NORMAL,
	};

	#ifdef CONFIG_AUDIO_USAGE_FOR_POWER_CONSUMPTION
	g_spk_flag = 0;
	g_spk_end_time = current_kernel_time();

	g_spk_total_time += (g_spk_end_time.tv_sec - g_spk_start_time.tv_sec);
	#endif

	if (spk & (BOTTOM_SPK_AMP_POS | BOTTOM_SPK_AMP_NEG)) {

		if (!msm8960_ext_bottom_spk_pamp)
			return;

		gpio_direction_output(BOTTOM_SPK_PAMP_GPIO, 0);
		gpio_free(BOTTOM_SPK_PAMP_GPIO);
		msm8960_ext_bottom_spk_pamp = 0;

		pr_debug("%s: sleeping 4 ms after turning off external"
			" Speaker Ampl\n", __func__);

		usleep_range(4000, 4000);

	} else if (spk & (TOP_SPK_AMP_POS | TOP_SPK_AMP_NEG)) {

		if (!msm8960_ext_top_spk_pamp)
			return;

		gpio_direction_output(TOP_SPK_PAMP_GPIO, 0);
		gpio_free(TOP_SPK_PAMP_GPIO);
		msm8960_ext_top_spk_pamp = 0;

		pr_debug("%s: sleeping 4 ms after turning off external"
			" HAC Ampl\n", __func__);

		usleep_range(4000, 4000);

	} else if (spk & (DOCK_SPK_AMP_POS | DOCK_SPK_AMP_NEG)) {

		mutex_lock(&audio_notifier_lock);

		if (!msm8960_ext_dock_spk_pamp) {
			mutex_unlock(&audio_notifier_lock);
			return;
		}

		gpio_direction_input(DOCK_SPK_PAMP_GPIO);
		gpio_free(DOCK_SPK_PAMP_GPIO);

		gpio_direction_input(USB_ID_ADC_GPIO);
		if (pm8xxx_gpio_config(USB_ID_ADC_GPIO, &param))
			pr_aud_err("%s: Failed to configure USB_ID_ADC PMIC"
				" gpio %u\n", __func__, USB_ID_ADC_GPIO);
		gpio_free(USB_ID_ADC_GPIO);
		msm8960_ext_dock_spk_pamp = 0;

		mutex_unlock(&audio_notifier_lock);

		pr_debug("%s: sleeping 4 ms after turning off external"
			" DOCK Ampl\n", __func__);

		usleep_range(4000, 4000);

	} else  {

		pr_aud_err("%s: ERROR : Invalid Ext Spk Ampl. spk = 0x%08x\n",
			__func__, spk);
		return;
	}
}
Beispiel #28
0
static long pn547_dev_ioctl(struct file *filp,
			   unsigned int cmd, unsigned long arg)
{
	struct pn547_dev *pn547_dev = filp->private_data;

	switch (cmd) {
	case PN547_SET_PWR:
		if (arg == 2) {
			/* power on with firmware download (requires hw reset)
			 */
			gpio_set_value_cansleep(pn547_dev->ven_gpio, 1);
			gpio_set_value(pn547_dev->firm_gpio, 1);
			usleep_range(10000, 10050);
			gpio_set_value_cansleep(pn547_dev->ven_gpio, 0);
			usleep_range(10000, 10050);
			gpio_set_value_cansleep(pn547_dev->ven_gpio, 1);
			usleep_range(10000, 10050);
			if (atomic_read(&pn547_dev->irq_enabled) == 0) {
				atomic_set(&pn547_dev->irq_enabled, 1);
				enable_irq(pn547_dev->client->irq);
				enable_irq_wake(pn547_dev->client->irq);
			}
			pr_info("%s power on with firmware, irq=%d\n", __func__,
				atomic_read(&pn547_dev->irq_enabled));
#ifdef CONFIG_NFC_PN547_8916_CLK_CTL
			pn547_dev->nfc_enable = 1;
			if (IS_ERR(pn547_dev->nfc_clock)) {
				pr_err("[NFC] %s: Couldn't get D1)\n",
							__func__);
			} else {
				//clk_put(pn547_dev->nfc_clock);
				pr_info("%s power set and clk_prepare_enable\n", __func__);
				if (clk_prepare_enable(pn547_dev->nfc_clock))
					pr_err("[NFC] %s: Couldn't prepare D1\n",
							__func__);
			}
#endif
		} else if (arg == 1) {
			/* power on */
			if (pn547_dev->conf_gpio)
				pn547_dev->conf_gpio();
			gpio_set_value(pn547_dev->firm_gpio, 0);
			gpio_set_value_cansleep(pn547_dev->ven_gpio, 1);
			usleep_range(10000, 10050);
			if (atomic_read(&pn547_dev->irq_enabled) == 0) {
				atomic_set(&pn547_dev->irq_enabled, 1);
				enable_irq(pn547_dev->client->irq);
				enable_irq_wake(pn547_dev->client->irq);
			}
			pr_info("%s power on, irq=%d\n", __func__,
				atomic_read(&pn547_dev->irq_enabled));
#ifdef CONFIG_NFC_PN547_8916_CLK_CTL
			pn547_dev->nfc_enable = 1;
			if (IS_ERR(pn547_dev->nfc_clock)) {
				pr_err("[NFC] %s: Couldn't get D1)\n",
							__func__);
			} else {
				//clk_put(pn547_dev->nfc_clock);
				pr_info("%s power on and clk_prepare_enable\n", __func__);
				if (clk_prepare_enable(pn547_dev->nfc_clock))
					pr_err("[NFC] %s: Couldn't prepare D1\n",
							__func__);
			}
#endif
		} else if (arg == 0) {
			/* power off */
			if (atomic_read(&pn547_dev->irq_enabled) == 1) {
				atomic_set(&pn547_dev->irq_enabled, 0);
				disable_irq_wake(pn547_dev->client->irq);
				disable_irq_nosync(pn547_dev->client->irq);
			}
			pr_info("%s power off, irq=%d\n", __func__,
				atomic_read(&pn547_dev->irq_enabled));
			gpio_set_value(pn547_dev->firm_gpio, 0);
			gpio_set_value_cansleep(pn547_dev->ven_gpio, 0);
			usleep_range(10000, 10050);
#ifdef CONFIG_NFC_PN547_8916_CLK_CTL
			pn547_dev->nfc_enable = 0;
			if(pn547_dev->nfc_clock)
			{
				clk_disable_unprepare(pn547_dev->nfc_clock);
				pr_info("%s power off and clk_disable_unprepare\n", __func__);
			}
#endif
		} else if (arg == 3) {
			pr_info("%s Read Cancel\n", __func__);
			pn547_dev->cancel_read = true;
			atomic_set(&pn547_dev->read_flag, 1);
			wake_up(&pn547_dev->read_wq);
		} else {
			pr_err("%s bad arg %lu\n", __func__, arg);
			return -EINVAL;
		}
		break;
	default:
		pr_err("%s bad ioctl %u\n", __func__, cmd);
		return -EINVAL;
	}

	return 0;
}