コード例 #1
0
/**
 * mid_thermal_probe - mfld thermal initialize
 * @ipcdev: ipc device structure
 *
 * mid thermal probe initializes the hardware and registers
 * all the sensors with the generic thermal framework. Can sleep.
 */
static int mid_thermal_probe(struct ipc_device *ipcdev)
{
	int ret;
	int i;
	ipcinfo = kzalloc(sizeof(struct ipc_info), GFP_KERNEL);
	if (!ipcinfo)
		return -ENOMEM;

	/* initialize mutex locks */
	mutex_init(&ipcinfo->cacheinfo.lock);

#ifdef CONFIG_BOARD_CTP
	/* Allocate ADC channels for all sensors */
	ipcinfo->therm_adc_handle = intel_mid_gpadc_alloc(MSIC_THERMAL_SENSORS,
					0x04 | CH_NEED_VREF | CH_NEED_VCALIB,
					0x04 | CH_NEED_VREF | CH_NEED_VCALIB,
					0x03 | CH_NEED_VCALIB,
					0x09 | CH_NEED_VREF | CH_NEED_VCALIB);
#else
	/* Allocate ADC channels for all sensors */
	ipcinfo->therm_adc_handle = intel_mid_gpadc_alloc(MSIC_THERMAL_SENSORS,
					0x08 | CH_NEED_VREF | CH_NEED_VCALIB,
					0x08 | CH_NEED_VREF | CH_NEED_VCALIB,
					0x0A | CH_NEED_VREF | CH_NEED_VCALIB,
					0x03 | CH_NEED_VCALIB);
#endif
	if (!ipcinfo->therm_adc_handle) {
		ret = -ENOMEM;
		goto alloc_fail;
	}

	/* Register each sensor with the generic thermal framework*/
	for (i = 0; i < MSIC_THERMAL_SENSORS; i++) {
		ipcinfo->tzd[i] = thermal_zone_device_register(name[i],
					0, 0, initialize_sensor(i),
					&tzd_ops, 0, 0, 0, 0);
		if (IS_ERR(ipcinfo->tzd[i]))
			goto reg_fail;
	}

	ipcinfo->ipcdev = ipcdev;
	ipc_set_drvdata(ipcdev, ipcinfo);
	return 0;

reg_fail:
	ret = PTR_ERR(ipcinfo->tzd[i]);
	while (--i >= 0)
		thermal_zone_device_unregister(ipcinfo->tzd[i]);
alloc_fail:
	kfree(ipcinfo);
	return ret;
}
コード例 #2
0
void *platform_init_battery_adc(int num_sensors, int chan_number, int flag)
{
	pr_debug("%s\n", __func__);

	/* Allocate ADC Channels */
	return
		(chgr_gpadc_handle = intel_mid_gpadc_alloc(num_sensors,
				  chan_number | flag));
}
コード例 #3
0
/* This function checks if the inserted accessory is thermal probe.
   If yes, keeps the bias and mux approprate for thermal
   probe so that the sensor driver can just read the adc voltage.
   Informs userspace and sensor driver of the insertion event
   and returns true
   If no, keeps the settings for Audio and returns false
*/
bool mfld_therm_probe_on_connect(struct snd_soc_jack *jack)
{
	int voltage = 0;
	int gpio_state;
	bool tp_status = false;
	void *adc_handle =  NULL;
	struct mfld_mc_private *ctx =
		snd_soc_card_get_drvdata(jack->codec->card);
	struct mfld_therm_probe_data  *tp_data_ptr;

	tp_data_ptr = &ctx->tp_data;

	gpio_state = mfld_read_jack_gpio(ctx);
	if (gpio_state != 0) {
		/* This situation can occur during bootup without any accessory
		   connected. We reach here because we initiate accessory
		   detection manually in the init function */
		pr_debug("In therm probe check; but no acc attached;"
			" returning\n");
		return tp_status;
	}
	/*If audio jack already connected;dont proceed with thermal probe det*/
	if (jack->status & (SND_JACK_HEADSET | SND_JACK_HEADPHONE)) {
		pr_debug("Therm probe det: spurious intr: Audio Jack "
					" already connected\n");
		return false;
	}
	/*If thermal probe already connected;dont proceed with det*/
	if (tp_data_ptr->tp_status) {
		pr_debug("Therm probe det: spurious intr:Thermal probe "
					" already connected\n");
		return true;
	}

	if (tp_data_ptr->tp_en_gpio < 0) {
		pr_err("therm probe gpio not valid; returning\n");
		/* If therm probe en gpio is not valid right channel
		   audio will also not work. But atleast enable left
		   channel audio(unground HSL/HSR) and return */
		snd_soc_update_bits(jack->codec, SN95031_BTNCTRL2, BIT(1), 0);
		return tp_status;
	}

	/* GPADC handle for therm probe detection; ADC channel is allocated
	   and deallocated in this fuction so that sensor driver can allocate
	   it and read the ADC after we report thermal probe connection*/
	adc_handle = intel_mid_gpadc_alloc(MFLD_THERM_PROBE_SENSOR,
			tp_data_ptr->tp_adc_ch_id);
	if (!adc_handle) {
		pr_err("therm probe adc handle not valid; returning\n");
		/* If therm probe adc handle is not valid, enable audio
		   and return. UnGround HSL and HSR of MSIC and Mux right
		   ch. headset pin to HSR of MSIC */
		snd_soc_update_bits(jack->codec, SN95031_BTNCTRL2, BIT(1), 0);
		gpio_direction_output(tp_data_ptr->tp_en_gpio, 1);
		return tp_status;
	}


	/* Ground HSL and HSR of MSIC */
	snd_soc_update_bits(jack->codec, SN95031_BTNCTRL2, BIT(1), BIT(1));
	/* Mux right ch. headset pin to ADC*/
	gpio_direction_output(tp_data_ptr->tp_en_gpio, 0);

	/* Enable mic bias 2 for therm probe check */
	mfld_jack_enable_mic_bias_gen(jack->codec, "AMIC2Bias");
	msleep(50);

	/* Read ADIN11 */
	intel_mid_gpadc_sample(adc_handle, 1, &voltage);
	voltage = (voltage * MFLD_ADC_ONE_LSB_MULTIPLIER) / 1000;

	intel_mid_gpadc_free(adc_handle);

	if (voltage < MFLD_TP_VOLT_THLD_LOW ||
			voltage > MFLD_TP_VOLT_THLD_HI) {

		/* Connected accessory is not thermal probe.
		   Enable audio jack detection and audio */
		/* UnGround HSL and HSR of MSIC */
		snd_soc_update_bits(jack->codec, SN95031_BTNCTRL2, BIT(1), 0);
		/* Mux right ch. headset pin to HSR of MSIC */
		gpio_direction_output(tp_data_ptr->tp_en_gpio, 1);
		mfld_jack_disable_mic_bias_gen(jack->codec, "AMIC2Bias");
		tp_status = false;
	} else {

		tp_status = true;
		if (tp_data_ptr->tp_status != tp_status) {
			tp_data_ptr->tp_status = tp_status;
			pr_debug("thermal probe connected\n");
		}
	}
	pr_debug("%s: therm_probe_state = %d voltage = %d\n", __func__,
			tp_status, voltage);
	return tp_status;
}