static int tps65217_charger_probe(struct platform_device *pdev) { struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent); struct tps65217_charger *charger; struct power_supply_config cfg = {}; int ret; dev_dbg(&pdev->dev, "%s\n", __func__); charger = devm_kzalloc(&pdev->dev, sizeof(*charger), GFP_KERNEL); if (!charger) return -ENOMEM; platform_set_drvdata(pdev, charger); charger->tps = tps; charger->dev = &pdev->dev; cfg.of_node = pdev->dev.of_node; cfg.drv_data = charger; charger->ac = devm_power_supply_register(&pdev->dev, &tps65217_charger_desc, &cfg); if (IS_ERR(charger->ac)) { dev_err(&pdev->dev, "failed: power supply register\n"); return PTR_ERR(charger->ac); } ret = tps65217_config_charger(charger); if (ret < 0) { dev_err(charger->dev, "charger config failed, err %d\n", ret); return ret; } charger->poll_task = kthread_run(tps65217_charger_poll_task, charger, "ktps65217charger"); if (IS_ERR(charger->poll_task)) { ret = PTR_ERR(charger->poll_task); dev_err(charger->dev, "Unable to run kthread err %d\n", ret); return ret; } return 0; }
static int max8903_probe(struct platform_device *pdev) { struct max8903_data *data; struct device *dev = &pdev->dev; struct max8903_pdata *pdata = pdev->dev.platform_data; struct power_supply_config psy_cfg = {}; int ret = 0; int gpio; int ta_in = 0; int usb_in = 0; data = devm_kzalloc(dev, sizeof(struct max8903_data), GFP_KERNEL); if (data == NULL) { dev_err(dev, "Cannot allocate memory.\n"); return -ENOMEM; } memcpy(&data->pdata, pdata, sizeof(struct max8903_pdata)); data->dev = dev; platform_set_drvdata(pdev, data); if (pdata->dc_valid == false && pdata->usb_valid == false) { dev_err(dev, "No valid power sources.\n"); return -EINVAL; } if (pdata->dc_valid) { if (pdata->dok && gpio_is_valid(pdata->dok) && pdata->dcm && gpio_is_valid(pdata->dcm)) { gpio = pdata->dok; /* PULL_UPed Interrupt */ ta_in = gpio_get_value(gpio) ? 0 : 1; gpio = pdata->dcm; /* Output */ gpio_set_value(gpio, ta_in); } else { dev_err(dev, "When DC is wired, DOK and DCM should" " be wired as well.\n"); return -EINVAL; } } else { if (pdata->dcm) { if (gpio_is_valid(pdata->dcm)) gpio_set_value(pdata->dcm, 0); else { dev_err(dev, "Invalid pin: dcm.\n"); return -EINVAL; } } } if (pdata->usb_valid) { if (pdata->uok && gpio_is_valid(pdata->uok)) { gpio = pdata->uok; usb_in = gpio_get_value(gpio) ? 0 : 1; } else { dev_err(dev, "When USB is wired, UOK should be wired." "as well.\n"); return -EINVAL; } } if (pdata->cen) { if (gpio_is_valid(pdata->cen)) { gpio_set_value(pdata->cen, (ta_in || usb_in) ? 0 : 1); } else { dev_err(dev, "Invalid pin: cen.\n"); return -EINVAL; } } if (pdata->chg) { if (!gpio_is_valid(pdata->chg)) { dev_err(dev, "Invalid pin: chg.\n"); return -EINVAL; } } if (pdata->flt) { if (!gpio_is_valid(pdata->flt)) { dev_err(dev, "Invalid pin: flt.\n"); return -EINVAL; } } if (pdata->usus) { if (!gpio_is_valid(pdata->usus)) { dev_err(dev, "Invalid pin: usus.\n"); return -EINVAL; } } data->fault = false; data->ta_in = ta_in; data->usb_in = usb_in; data->psy_desc.name = "max8903_charger"; data->psy_desc.type = (ta_in) ? POWER_SUPPLY_TYPE_MAINS : ((usb_in) ? POWER_SUPPLY_TYPE_USB : POWER_SUPPLY_TYPE_BATTERY); data->psy_desc.get_property = max8903_get_property; data->psy_desc.properties = max8903_charger_props; data->psy_desc.num_properties = ARRAY_SIZE(max8903_charger_props); psy_cfg.drv_data = data; data->psy = devm_power_supply_register(dev, &data->psy_desc, &psy_cfg); if (IS_ERR(data->psy)) { dev_err(dev, "failed: power supply register.\n"); return PTR_ERR(data->psy); } if (pdata->dc_valid) { ret = devm_request_threaded_irq(dev, gpio_to_irq(pdata->dok), NULL, max8903_dcin, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_ONESHOT, "MAX8903 DC IN", data); if (ret) { dev_err(dev, "Cannot request irq %d for DC (%d)\n", gpio_to_irq(pdata->dok), ret); return ret; } } if (pdata->usb_valid) { ret = devm_request_threaded_irq(dev, gpio_to_irq(pdata->uok), NULL, max8903_usbin, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_ONESHOT, "MAX8903 USB IN", data); if (ret) { dev_err(dev, "Cannot request irq %d for USB (%d)\n", gpio_to_irq(pdata->uok), ret); return ret; } } if (pdata->flt) { ret = devm_request_threaded_irq(dev, gpio_to_irq(pdata->flt), NULL, max8903_fault, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING | IRQF_ONESHOT, "MAX8903 Fault", data); if (ret) { dev_err(dev, "Cannot request irq %d for Fault (%d)\n", gpio_to_irq(pdata->flt), ret); return ret; } } return 0; }
static int olpc_battery_probe(struct platform_device *pdev) { struct power_supply_config bat_psy_cfg = {}; struct power_supply_config ac_psy_cfg = {}; struct olpc_battery_data *data; uint8_t status; uint8_t ecver; int ret; data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM; platform_set_drvdata(pdev, data); /* See if the EC is already there and get the EC revision */ ret = olpc_ec_cmd(EC_FIRMWARE_REV, NULL, 0, &ecver, 1); if (ret) return ret; if (of_find_compatible_node(NULL, NULL, "olpc,xo1.75-ec")) { /* XO 1.75 */ data->new_proto = true; data->little_endian = true; } else if (ecver > 0x44) { /* XO 1 or 1.5 with a new EC firmware. */ data->new_proto = true; } else if (ecver < 0x44) { /* * We've seen a number of EC protocol changes; this driver * requires the latest EC protocol, supported by 0x44 and above. */ printk(KERN_NOTICE "OLPC EC version 0x%02x too old for " "battery driver.\n", ecver); return -ENXIO; } ret = olpc_ec_cmd(EC_BAT_STATUS, NULL, 0, &status, 1); if (ret) return ret; /* Ignore the status. It doesn't actually matter */ ac_psy_cfg.of_node = pdev->dev.of_node; ac_psy_cfg.drv_data = data; data->olpc_ac = devm_power_supply_register(&pdev->dev, &olpc_ac_desc, &ac_psy_cfg); if (IS_ERR(data->olpc_ac)) return PTR_ERR(data->olpc_ac); if (of_device_is_compatible(pdev->dev.of_node, "olpc,xo1.5-battery")) { /* XO-1.5 */ olpc_bat_desc.properties = olpc_xo15_bat_props; olpc_bat_desc.num_properties = ARRAY_SIZE(olpc_xo15_bat_props); } else { /* XO-1 */ olpc_bat_desc.properties = olpc_xo1_bat_props; olpc_bat_desc.num_properties = ARRAY_SIZE(olpc_xo1_bat_props); } bat_psy_cfg.of_node = pdev->dev.of_node; bat_psy_cfg.drv_data = data; bat_psy_cfg.attr_grp = olpc_bat_sysfs_groups; data->olpc_bat = devm_power_supply_register(&pdev->dev, &olpc_bat_desc, &bat_psy_cfg); if (IS_ERR(data->olpc_bat)) return PTR_ERR(data->olpc_bat); if (olpc_ec_wakeup_available()) { device_set_wakeup_capable(&data->olpc_ac->dev, true); device_set_wakeup_capable(&data->olpc_bat->dev, true); } return 0; }
static int bq24735_charger_probe(struct i2c_client *client, const struct i2c_device_id *id) { int ret; struct bq24735 *charger; struct power_supply_desc *supply_desc; struct power_supply_config psy_cfg = {}; char *name; charger = devm_kzalloc(&client->dev, sizeof(*charger), GFP_KERNEL); if (!charger) return -ENOMEM; charger->pdata = client->dev.platform_data; if (IS_ENABLED(CONFIG_OF) && !charger->pdata && client->dev.of_node) charger->pdata = bq24735_parse_dt_data(client); if (!charger->pdata) { dev_err(&client->dev, "no platform data provided\n"); return -EINVAL; } name = (char *)charger->pdata->name; if (!name) { name = devm_kasprintf(&client->dev, GFP_KERNEL, "bq24735@%s", dev_name(&client->dev)); if (!name) { dev_err(&client->dev, "Failed to alloc device name\n"); return -ENOMEM; } } charger->client = client; supply_desc = &charger->charger_desc; supply_desc->name = name; supply_desc->type = POWER_SUPPLY_TYPE_MAINS; supply_desc->properties = bq24735_charger_properties; supply_desc->num_properties = ARRAY_SIZE(bq24735_charger_properties); supply_desc->get_property = bq24735_charger_get_property; psy_cfg.supplied_to = charger->pdata->supplied_to; psy_cfg.num_supplicants = charger->pdata->num_supplicants; psy_cfg.of_node = client->dev.of_node; psy_cfg.drv_data = charger; i2c_set_clientdata(client, charger); ret = bq24735_read_word(client, BQ24735_MANUFACTURER_ID); if (ret < 0) { dev_err(&client->dev, "Failed to read manufacturer id : %d\n", ret); return ret; } else if (ret != 0x0040) { dev_err(&client->dev, "manufacturer id mismatch. 0x0040 != 0x%04x\n", ret); return -ENODEV; } ret = bq24735_read_word(client, BQ24735_DEVICE_ID); if (ret < 0) { dev_err(&client->dev, "Failed to read device id : %d\n", ret); return ret; } else if (ret != 0x000B) { dev_err(&client->dev, "device id mismatch. 0x000b != 0x%04x\n", ret); return -ENODEV; } if (gpio_is_valid(charger->pdata->status_gpio)) { ret = devm_gpio_request(&client->dev, charger->pdata->status_gpio, name); if (ret) { dev_err(&client->dev, "Failed GPIO request for GPIO %d: %d\n", charger->pdata->status_gpio, ret); } charger->pdata->status_gpio_valid = !ret; } ret = bq24735_config_charger(charger); if (ret < 0) { dev_err(&client->dev, "failed in configuring charger"); return ret; } /* check for AC adapter presence */ if (bq24735_charger_is_present(charger)) { ret = bq24735_enable_charging(charger); if (ret < 0) { dev_err(&client->dev, "Failed to enable charging\n"); return ret; } } charger->charger = devm_power_supply_register(&client->dev, supply_desc, &psy_cfg); if (IS_ERR(charger->charger)) { ret = PTR_ERR(charger->charger); dev_err(&client->dev, "Failed to register power supply: %d\n", ret); return ret; } if (client->irq) { ret = devm_request_threaded_irq(&client->dev, client->irq, NULL, bq24735_charger_isr, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, supply_desc->name, charger->charger); if (ret) { dev_err(&client->dev, "Unable to register IRQ %d err %d\n", client->irq, ret); return ret; } } return 0; }
static int max77650_charger_probe(struct platform_device *pdev) { struct power_supply_config pscfg = {}; struct max77650_charger_data *chg; struct power_supply *battery; struct device *dev, *parent; int rv, chg_irq, chgin_irq; unsigned int prop; dev = &pdev->dev; parent = dev->parent; chg = devm_kzalloc(dev, sizeof(*chg), GFP_KERNEL); if (!chg) return -ENOMEM; platform_set_drvdata(pdev, chg); chg->map = dev_get_regmap(parent, NULL); if (!chg->map) return -ENODEV; chg->dev = dev; pscfg.of_node = dev->of_node; pscfg.drv_data = chg; chg_irq = platform_get_irq_byname(pdev, "CHG"); if (chg_irq < 0) return chg_irq; chgin_irq = platform_get_irq_byname(pdev, "CHGIN"); if (chgin_irq < 0) return chgin_irq; rv = devm_request_any_context_irq(dev, chg_irq, max77650_charger_check_status, IRQF_ONESHOT, "chg", chg); if (rv < 0) return rv; rv = devm_request_any_context_irq(dev, chgin_irq, max77650_charger_check_status, IRQF_ONESHOT, "chgin", chg); if (rv < 0) return rv; battery = devm_power_supply_register(dev, &max77650_battery_desc, &pscfg); if (IS_ERR(battery)) return PTR_ERR(battery); rv = of_property_read_u32(dev->of_node, "input-voltage-min-microvolt", &prop); if (rv == 0) { rv = max77650_charger_set_vchgin_min(chg, prop); if (rv) return rv; } rv = of_property_read_u32(dev->of_node, "input-current-limit-microamp", &prop); if (rv == 0) { rv = max77650_charger_set_ichgin_lim(chg, prop); if (rv) return rv; } return max77650_charger_enable(chg); }
static int gpio_charger_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; const struct gpio_charger_platform_data *pdata = dev->platform_data; struct power_supply_config psy_cfg = {}; struct gpio_charger *gpio_charger; struct power_supply_desc *charger_desc; unsigned long flags; int irq, ret; if (!pdata && !dev->of_node) { dev_err(dev, "No platform data\n"); return -ENOENT; } gpio_charger = devm_kzalloc(dev, sizeof(*gpio_charger), GFP_KERNEL); if (!gpio_charger) return -ENOMEM; /* * This will fetch a GPIO descriptor from device tree, ACPI or * boardfile descriptor tables. It's good to try this first. */ gpio_charger->gpiod = devm_gpiod_get(dev, NULL, GPIOD_IN); /* * If this fails and we're not using device tree, try the * legacy platform data method. */ if (IS_ERR(gpio_charger->gpiod) && !dev->of_node) { /* Non-DT: use legacy GPIO numbers */ if (!gpio_is_valid(pdata->gpio)) { dev_err(dev, "Invalid gpio pin in pdata\n"); return -EINVAL; } flags = GPIOF_IN; if (pdata->gpio_active_low) flags |= GPIOF_ACTIVE_LOW; ret = devm_gpio_request_one(dev, pdata->gpio, flags, dev_name(dev)); if (ret) { dev_err(dev, "Failed to request gpio pin: %d\n", ret); return ret; } /* Then convert this to gpiod for now */ gpio_charger->gpiod = gpio_to_desc(pdata->gpio); } else if (IS_ERR(gpio_charger->gpiod)) { /* Just try again if this happens */ if (PTR_ERR(gpio_charger->gpiod) == -EPROBE_DEFER) return -EPROBE_DEFER; dev_err(dev, "error getting GPIO descriptor\n"); return PTR_ERR(gpio_charger->gpiod); } charger_desc = &gpio_charger->charger_desc; charger_desc->properties = gpio_charger_properties; charger_desc->num_properties = ARRAY_SIZE(gpio_charger_properties); charger_desc->get_property = gpio_charger_get_property; psy_cfg.of_node = dev->of_node; psy_cfg.drv_data = gpio_charger; if (pdata) { charger_desc->name = pdata->name; charger_desc->type = pdata->type; psy_cfg.supplied_to = pdata->supplied_to; psy_cfg.num_supplicants = pdata->num_supplicants; } else { charger_desc->name = dev->of_node->name; charger_desc->type = gpio_charger_get_type(dev); } if (!charger_desc->name) charger_desc->name = pdev->name; gpio_charger->charger = devm_power_supply_register(dev, charger_desc, &psy_cfg); if (IS_ERR(gpio_charger->charger)) { ret = PTR_ERR(gpio_charger->charger); dev_err(dev, "Failed to register power supply: %d\n", ret); return ret; } irq = gpiod_to_irq(gpio_charger->gpiod); if (irq > 0) { ret = devm_request_any_context_irq(dev, irq, gpio_charger_irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, dev_name(dev), gpio_charger->charger); if (ret < 0) dev_warn(dev, "Failed to request irq: %d\n", ret); else gpio_charger->irq = irq; } platform_set_drvdata(pdev, gpio_charger); device_init_wakeup(dev, 1); return 0; }
static int axp20x_usb_power_probe(struct platform_device *pdev) { struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent); struct power_supply_config psy_cfg = {}; struct axp20x_usb_power *power; static const char * const axp20x_irq_names[] = { "VBUS_PLUGIN", "VBUS_REMOVAL", "VBUS_VALID", "VBUS_NOT_VALID", NULL }; static const char * const axp22x_irq_names[] = { "VBUS_PLUGIN", "VBUS_REMOVAL", NULL }; const char * const *irq_names; const struct power_supply_desc *usb_power_desc; int i, irq, ret; if (!of_device_is_available(pdev->dev.of_node)) return -ENODEV; if (!axp20x) { dev_err(&pdev->dev, "Parent drvdata not set\n"); return -EINVAL; } power = devm_kzalloc(&pdev->dev, sizeof(*power), GFP_KERNEL); if (!power) return -ENOMEM; power->axp20x_id = (enum axp20x_variants)of_device_get_match_data( &pdev->dev); power->np = pdev->dev.of_node; power->regmap = axp20x->regmap; if (power->axp20x_id == AXP202_ID) { /* Enable vbus valid checking */ ret = regmap_update_bits(power->regmap, AXP20X_VBUS_MON, AXP20X_VBUS_MON_VBUS_VALID, AXP20X_VBUS_MON_VBUS_VALID); if (ret) return ret; if (IS_ENABLED(CONFIG_AXP20X_ADC)) ret = configure_iio_channels(pdev, power); else ret = configure_adc_registers(power); if (ret) return ret; usb_power_desc = &axp20x_usb_power_desc; irq_names = axp20x_irq_names; } else if (power->axp20x_id == AXP221_ID || power->axp20x_id == AXP223_ID) { usb_power_desc = &axp22x_usb_power_desc; irq_names = axp22x_irq_names; } else { dev_err(&pdev->dev, "Unsupported AXP variant: %ld\n", axp20x->variant); return -EINVAL; } psy_cfg.of_node = pdev->dev.of_node; psy_cfg.drv_data = power; power->supply = devm_power_supply_register(&pdev->dev, usb_power_desc, &psy_cfg); if (IS_ERR(power->supply)) return PTR_ERR(power->supply); /* Request irqs after registering, as irqs may trigger immediately */ for (i = 0; irq_names[i]; i++) { irq = platform_get_irq_byname(pdev, irq_names[i]); if (irq < 0) { dev_warn(&pdev->dev, "No IRQ for %s: %d\n", irq_names[i], irq); continue; } irq = regmap_irq_get_virq(axp20x->regmap_irqc, irq); ret = devm_request_any_context_irq(&pdev->dev, irq, axp20x_usb_power_irq, 0, DRVNAME, power); if (ret < 0) dev_warn(&pdev->dev, "Error requesting %s IRQ: %d\n", irq_names[i], ret); } return 0; }