/** * 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; }
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)); }
/* 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; }