示例#1
0
static int twl4030_madc_battery_probe(struct platform_device *pdev)
{
	struct twl4030_madc_battery *twl4030_madc_bat;
	struct twl4030_madc_bat_platform_data *pdata = pdev->dev.platform_data;
	struct power_supply_config psy_cfg = {};
	int ret = 0;

	twl4030_madc_bat = devm_kzalloc(&pdev->dev, sizeof(*twl4030_madc_bat),
				GFP_KERNEL);
	if (!twl4030_madc_bat)
		return -ENOMEM;

	twl4030_madc_bat->channel_temp = iio_channel_get(&pdev->dev, "temp");
	if (IS_ERR(twl4030_madc_bat->channel_temp)) {
		ret = PTR_ERR(twl4030_madc_bat->channel_temp);
		goto err;
	}

	twl4030_madc_bat->channel_ichg = iio_channel_get(&pdev->dev, "ichg");
	if (IS_ERR(twl4030_madc_bat->channel_ichg)) {
		ret = PTR_ERR(twl4030_madc_bat->channel_ichg);
		goto err_temp;
	}

	twl4030_madc_bat->channel_vbat = iio_channel_get(&pdev->dev, "vbat");
	if (IS_ERR(twl4030_madc_bat->channel_vbat)) {
		ret = PTR_ERR(twl4030_madc_bat->channel_vbat);
		goto err_ichg;
	}

	/* sort charging and discharging calibration data */
	sort(pdata->charging, pdata->charging_size,
		sizeof(struct twl4030_madc_bat_calibration),
		twl4030_cmp, NULL);
	sort(pdata->discharging, pdata->discharging_size,
		sizeof(struct twl4030_madc_bat_calibration),
		twl4030_cmp, NULL);

	twl4030_madc_bat->pdata = pdata;
	platform_set_drvdata(pdev, twl4030_madc_bat);
	psy_cfg.drv_data = twl4030_madc_bat;
	twl4030_madc_bat->psy = power_supply_register(&pdev->dev,
						      &twl4030_madc_bat_desc,
						      &psy_cfg);
	if (IS_ERR(twl4030_madc_bat->psy)) {
		ret = PTR_ERR(twl4030_madc_bat->psy);
		goto err_vbat;
	}

	return 0;

err_vbat:
	iio_channel_release(twl4030_madc_bat->channel_vbat);
err_ichg:
	iio_channel_release(twl4030_madc_bat->channel_ichg);
err_temp:
	iio_channel_release(twl4030_madc_bat->channel_temp);
err:
	return ret;
}
示例#2
0
static int rx51_battery_probe(struct platform_device *pdev)
{
	struct power_supply_config psy_cfg = {};
	struct rx51_device_info *di;
	int ret;

	di = devm_kzalloc(&pdev->dev, sizeof(*di), GFP_KERNEL);
	if (!di)
		return -ENOMEM;

	platform_set_drvdata(pdev, di);

	di->dev = &pdev->dev;
	di->bat_desc.name = "rx51-battery";
	di->bat_desc.type = POWER_SUPPLY_TYPE_BATTERY;
	di->bat_desc.properties = rx51_battery_props;
	di->bat_desc.num_properties = ARRAY_SIZE(rx51_battery_props);
	di->bat_desc.get_property = rx51_battery_get_property;

	psy_cfg.drv_data = di;

	di->channel_temp = iio_channel_get(di->dev, "temp");
	if (IS_ERR(di->channel_temp)) {
		ret = PTR_ERR(di->channel_temp);
		goto error;
	}

	di->channel_bsi  = iio_channel_get(di->dev, "bsi");
	if (IS_ERR(di->channel_bsi)) {
		ret = PTR_ERR(di->channel_bsi);
		goto error_channel_temp;
	}

	di->channel_vbat = iio_channel_get(di->dev, "vbat");
	if (IS_ERR(di->channel_vbat)) {
		ret = PTR_ERR(di->channel_vbat);
		goto error_channel_bsi;
	}

	di->bat = power_supply_register(di->dev, &di->bat_desc, &psy_cfg);
	if (IS_ERR(di->bat)) {
		ret = PTR_ERR(di->bat);
		goto error_channel_vbat;
	}

	return 0;

error_channel_vbat:
	iio_channel_release(di->channel_vbat);
error_channel_bsi:
	iio_channel_release(di->channel_bsi);
error_channel_temp:
	iio_channel_release(di->channel_temp);
error:

	return ret;
}
示例#3
0
static void lp8788_setup_adc_channel(struct lp8788_charger *pchg)
{
	struct lp8788_charger_platform_data *pdata = pchg->pdata;
	struct device *dev = pchg->lp->dev;
	struct iio_channel *chan;
	enum lp8788_adc_id id;
	const char *chan_name[LPADC_MAX] = {
		[LPADC_VBATT_5P5] = "vbatt-5p5",
		[LPADC_VBATT_6P0] = "vbatt-6p0",
		[LPADC_VBATT_5P0] = "vbatt-5p0",
		[LPADC_ADC1]      = "adc1",
		[LPADC_ADC2]      = "adc2",
		[LPADC_ADC3]      = "adc3",
		[LPADC_ADC4]      = "adc4",
	};

	if (!pdata)
		return;

	id = pdata->vbatt_adc;
	switch (id) {
	case LPADC_VBATT_5P5:
	case LPADC_VBATT_6P0:
	case LPADC_VBATT_5P0:
		chan = iio_channel_get(NULL, chan_name[id]);
		pchg->chan[LP8788_VBATT] = IS_ERR(chan) ? NULL : chan;
		break;
	default:
		dev_err(dev, "invalid ADC id for VBATT: %d\n", id);
		pchg->chan[LP8788_VBATT] = NULL;
		break;
	}

	id = pdata->batt_temp_adc;
	switch (id) {
	case LPADC_ADC1:
	case LPADC_ADC2:
	case LPADC_ADC3:
	case LPADC_ADC4:
		chan = iio_channel_get(NULL, chan_name[id]);
		pchg->chan[LP8788_BATT_TEMP] = IS_ERR(chan) ? NULL : chan;
		break;
	default:
		dev_err(dev, "invalid ADC id for BATT_TEMP : %d\n", id);
		pchg->chan[LP8788_BATT_TEMP] = NULL;
		break;
	}
}
/**
 * pmic_read_adc_val - read ADC value of specified sensors
 * @channel: channel of the sensor to be sampled
 * @sensor_val: pointer to the charger property to hold sampled value
 * @chc :  battery info pointer
 *
 * Returns 0 if success
 */
static int pmic_read_adc_val(const char *map, const char *name,
			int *raw_val, struct pmic_fg_info *info)
{
	int ret, val;
	struct iio_channel *indio_chan;

	indio_chan = iio_channel_get(NULL, name);
	if (IS_ERR_OR_NULL(indio_chan)) {
		ret = PTR_ERR(indio_chan);
		goto exit;
	}
	ret = iio_read_channel_raw(indio_chan, &val);
	if (ret) {
		dev_err(&info->pdev->dev, "IIO channel read error\n");
		goto err_exit;
	}

	dev_dbg(&info->pdev->dev, "adc raw val=%x\n", val);
	*raw_val = val;

err_exit:
	iio_channel_release(indio_chan);
exit:
	return ret;
}
示例#5
0
static void lp8788_setup_adc_channel(struct device *dev,
				struct lp8788_charger *pchg)
{
	struct lp8788_charger_platform_data *pdata = pchg->pdata;
	struct iio_channel *chan;

	if (!pdata)
		return;

	/* ADC channel for battery voltage */
	chan = iio_channel_get(dev, pdata->adc_vbatt);
	pchg->chan[LP8788_VBATT] = IS_ERR(chan) ? NULL : chan;

	/* ADC channel for battery temperature */
	chan = iio_channel_get(dev, pdata->adc_batt_temp);
	pchg->chan[LP8788_BATT_TEMP] = IS_ERR(chan) ? NULL : chan;
}
示例#6
0
static int gadc_thermal_probe(struct platform_device *pdev)
{
	struct gadc_thermal_info *gti;
	int ret;

	if (!pdev->dev.of_node) {
		dev_err(&pdev->dev, "Only DT based supported\n");
		return -ENODEV;
	}

	gti = devm_kzalloc(&pdev->dev, sizeof(*gti), GFP_KERNEL);
	if (!gti)
		return -ENOMEM;

	ret = gadc_thermal_read_linear_lookup_table(&pdev->dev, gti);
	if (ret < 0)
		return ret;

	gti->dev = &pdev->dev;
	platform_set_drvdata(pdev, gti);

	gti->channel = iio_channel_get(&pdev->dev, "sensor-channel");
	if (IS_ERR(gti->channel)) {
		ret = PTR_ERR(gti->channel);
		dev_err(&pdev->dev, "IIO channel not found: %d\n", ret);
		return ret;
	}

	gti->tz_dev = thermal_zone_of_sensor_register(&pdev->dev, 0,
						      gti, &gadc_thermal_ops);
	if (IS_ERR(gti->tz_dev)) {
		ret = PTR_ERR(gti->tz_dev);
		dev_err(&pdev->dev, "Thermal zone sensor register failed: %d\n",
			ret);
		goto sensor_fail;
	}

	return 0;

sensor_fail:
	iio_channel_release(gti->channel);

	return ret;
}
示例#7
0
文件: sdcv.c 项目: BORETS24/za580
/*
 * sd_cv_batt_id_resistor - calculate the battery id resistor (Ohm)
 * return - the resistor value (Ohm)
 */
int sd_cv_batt_id_resistor()
{
    int ret;
    int val = 0;
    int resistor = 0;
    int adc = 0;
    int auto_cur_sel = 0;
    int battid_cursrc = 0;
    struct iio_channel *indio_chan = NULL;

    /* Get battid pmic channel */
    indio_chan = iio_channel_get(NULL, SDCV_BATTID_CHANNEL_NAME);
    if (IS_ERR_OR_NULL(indio_chan)) {
        pr_err("%s: IIO channel get error!!\n", __func__);
        return -1;
    }

    /* Read pmic battid ADC */
#if 0
    ret = iio_read_channel_raw(indio_chan, &val);
    if (ret) {
        pr_err("%s: unable to read batid", __func__);
        return -1;
    }
    pr_info("%s: IIO channel read Sucess, val=%.3X\n", __func__, val);
#endif

    adc = sd_cv_get_adc_value(SDCV_BATTIDRSLTH_REG, &auto_cur_sel);
    if (adc < 0 || auto_cur_sel == 0) {
        pr_err("%s: fail to get batt id result from 0x%X",
               __func__, SDCV_BATTIDRSLTH_REG);
        return -1;
    }
    pr_info("%s: adc=0x%X, auto_cur_sel=%d\n", __func__, adc, auto_cur_sel);

    /* The formula for calculating the battery id resistor */
    resistor = adc * 293 * 1000 / auto_cur_sel;

    /* Release adc channel */
    iio_channel_release(indio_chan);

    return resistor;
}
示例#8
0
int shady_cove_get_id(struct dwc_otg2 *otg)
{
	u8 schgrirq1;
	struct iio_channel *chan;
	int ret, rid, id = RID_UNKNOWN;

	ret = intel_scu_ipc_ioread8(PMIC_SCHGRIRQ1, &schgrirq1);
	if (ret) {
		otg_err(otg, "Fail to read id\n");
		return id;
	}

	/* PMIC_SCHGRIRQ1_SUSBIDDET bit definition:
	 * 0 = RID_A/B/C ; 1 = RID_GND ; 2 = RID_FLOAT */
	if (schgrirq1 & PMIC_SCHGRIRQ1_SUSBIDDET(2))
		return RID_FLOAT;
	else if (schgrirq1 & PMIC_SCHGRIRQ1_SUSBIDDET(1))
		return RID_GND;

	chan = iio_channel_get(NULL, "USBID");
	if (IS_ERR_OR_NULL(chan)) {
		otg_err(otg, "%s: Fail to get USBID channel\n", __func__);
		return id;
	}

	ret = iio_read_channel_raw(chan, &rid);
	if (ret) {
		otg_err(otg, "%s: Fail to read USBID channel", __func__);
		goto done;
	}

	if ((rid > 11150) && (rid < 13640))
		id = RID_A;
	else if ((rid > 6120) && (rid < 7480))
		id = RID_B;
	else if ((rid > 3285) && (rid < 4015))
		id = RID_C;

done:

	iio_channel_release(chan);
	return id;
}
示例#9
0
文件: sdcv.c 项目: BORETS24/za580
/*
 * sd_cv_batt_vol - calculate the battery voltage
 * return - the battery voltage value (mV)
 */
int sd_cv_batt_vol()
{
    int ret;
    int val = 0;
    int volt = 0;
    int adc = 0;
    int battid_cursrc = 0;
    struct iio_channel *indio_chan = NULL;

    /* Get vbat pmic channel */
    indio_chan = iio_channel_get(NULL, SDCV_VBAT_CHANNEL_NAME);
    if (IS_ERR_OR_NULL(indio_chan)) {
        pr_err("%s: IIO channel get error!!\n", __func__);
        return -1;
    }

    /* Read pmic vbat ADC */
    ret = iio_read_channel_raw(indio_chan, &val);
    if (ret) {
        pr_err("%s: unable to read vbat", __func__);
        return -1;
    }
    pr_debug("%s: IIO channel read Sucess, val=%.3X\n", __func__, val);

    adc = sd_cv_get_adc_value(SDCV_VBATRSLTH_REG, NULL);
    if (adc < 0) {
        pr_err("%s: fail to get vbat result from 0x%X",
               __func__, SDCV_VBATRSLTH_REG);
        return -1;
    }
    pr_debug("%s: adc=0x%X\n", __func__, adc);

    /* The formula for calculating the battery voltage */
    volt = adc * 1250 / 1000;

    /* Release adc channel */
    iio_channel_release(indio_chan);

    return volt;
}
示例#10
0
static int gab_probe(struct platform_device *pdev)
{
	struct gab *adc_bat;
	struct power_supply_desc *psy_desc;
	struct power_supply_config psy_cfg = {};
	struct gab_platform_data *pdata = pdev->dev.platform_data;
	enum power_supply_property *properties;
	int ret = 0;
	int chan;
	int index = 0;

	adc_bat = devm_kzalloc(&pdev->dev, sizeof(*adc_bat), GFP_KERNEL);
	if (!adc_bat) {
		dev_err(&pdev->dev, "failed to allocate memory\n");
		return -ENOMEM;
	}

	psy_cfg.drv_data = adc_bat;
	psy_desc = &adc_bat->psy_desc;
	psy_desc->name = pdata->battery_info.name;

	/* bootup default values for the battery */
	adc_bat->cable_plugged = false;
	adc_bat->status = POWER_SUPPLY_STATUS_DISCHARGING;
	psy_desc->type = POWER_SUPPLY_TYPE_BATTERY;
	psy_desc->get_property = gab_get_property;
	psy_desc->external_power_changed = gab_ext_power_changed;
	adc_bat->pdata = pdata;

	/*
	 * copying the static properties and allocating extra memory for holding
	 * the extra configurable properties received from platform data.
	 */
	psy_desc->properties = kcalloc(ARRAY_SIZE(gab_props) +
					ARRAY_SIZE(gab_chan_name),
					sizeof(*psy_desc->properties),
					GFP_KERNEL);
	if (!psy_desc->properties) {
		ret = -ENOMEM;
		goto first_mem_fail;
	}

	memcpy(psy_desc->properties, gab_props, sizeof(gab_props));
	properties = (enum power_supply_property *)
			((char *)psy_desc->properties + sizeof(gab_props));

	/*
	 * getting channel from iio and copying the battery properties
	 * based on the channel supported by consumer device.
	 */
	for (chan = 0; chan < ARRAY_SIZE(gab_chan_name); chan++) {
		adc_bat->channel[chan] = iio_channel_get(&pdev->dev,
							 gab_chan_name[chan]);
		if (IS_ERR(adc_bat->channel[chan])) {
			ret = PTR_ERR(adc_bat->channel[chan]);
			adc_bat->channel[chan] = NULL;
		} else {
			/* copying properties for supported channels only */
			memcpy(properties + sizeof(*(psy_desc->properties)) * index,
					&gab_dyn_props[chan],
					sizeof(gab_dyn_props[chan]));
			index++;
		}
	}

	/* none of the channels are supported so let's bail out */
	if (index == 0) {
		ret = -ENODEV;
		goto second_mem_fail;
	}

	/*
	 * Total number of properties is equal to static properties
	 * plus the dynamic properties.Some properties may not be set
	 * as come channels may be not be supported by the device.So
	 * we need to take care of that.
	 */
	psy_desc->num_properties = ARRAY_SIZE(gab_props) + index;

	adc_bat->psy = power_supply_register(&pdev->dev, psy_desc, &psy_cfg);
	if (IS_ERR(adc_bat->psy)) {
		ret = PTR_ERR(adc_bat->psy);
		goto err_reg_fail;
	}

	INIT_DELAYED_WORK(&adc_bat->bat_work, gab_work);

	if (gpio_is_valid(pdata->gpio_charge_finished)) {
		int irq;
		ret = gpio_request(pdata->gpio_charge_finished, "charged");
		if (ret)
			goto gpio_req_fail;

		irq = gpio_to_irq(pdata->gpio_charge_finished);
		ret = request_any_context_irq(irq, gab_charged,
				IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
				"battery charged", adc_bat);
		if (ret < 0)
			goto err_gpio;
	}

	platform_set_drvdata(pdev, adc_bat);

	/* Schedule timer to check current status */
	schedule_delayed_work(&adc_bat->bat_work,
			msecs_to_jiffies(0));
	return 0;

err_gpio:
	gpio_free(pdata->gpio_charge_finished);
gpio_req_fail:
	power_supply_unregister(adc_bat->psy);
err_reg_fail:
	for (chan = 0; chan < ARRAY_SIZE(gab_chan_name); chan++) {
		if (adc_bat->channel[chan])
			iio_channel_release(adc_bat->channel[chan]);
	}
second_mem_fail:
	kfree(psy_desc->properties);
first_mem_fail:
	return ret;
}