0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/module.h>
0009 #include <linux/gpio/consumer.h>
0010 #include <linux/i2c.h>
0011 #include <linux/interrupt.h>
0012 #include <linux/irq.h>
0013 #include <linux/power_supply.h>
0014 #include <linux/slab.h>
0015 #include <linux/z2_battery.h>
0016
0017 #define Z2_DEFAULT_NAME "Z2"
0018
0019 struct z2_charger {
0020 struct z2_battery_info *info;
0021 struct gpio_desc *charge_gpiod;
0022 int bat_status;
0023 struct i2c_client *client;
0024 struct power_supply *batt_ps;
0025 struct power_supply_desc batt_ps_desc;
0026 struct mutex work_lock;
0027 struct work_struct bat_work;
0028 };
0029
0030 static unsigned long z2_read_bat(struct z2_charger *charger)
0031 {
0032 int data;
0033 data = i2c_smbus_read_byte_data(charger->client,
0034 charger->info->batt_I2C_reg);
0035 if (data < 0)
0036 return 0;
0037
0038 return data * charger->info->batt_mult / charger->info->batt_div;
0039 }
0040
0041 static int z2_batt_get_property(struct power_supply *batt_ps,
0042 enum power_supply_property psp,
0043 union power_supply_propval *val)
0044 {
0045 struct z2_charger *charger = power_supply_get_drvdata(batt_ps);
0046 struct z2_battery_info *info = charger->info;
0047
0048 switch (psp) {
0049 case POWER_SUPPLY_PROP_STATUS:
0050 val->intval = charger->bat_status;
0051 break;
0052 case POWER_SUPPLY_PROP_TECHNOLOGY:
0053 val->intval = info->batt_tech;
0054 break;
0055 case POWER_SUPPLY_PROP_VOLTAGE_NOW:
0056 if (info->batt_I2C_reg >= 0)
0057 val->intval = z2_read_bat(charger);
0058 else
0059 return -EINVAL;
0060 break;
0061 case POWER_SUPPLY_PROP_VOLTAGE_MAX:
0062 if (info->max_voltage >= 0)
0063 val->intval = info->max_voltage;
0064 else
0065 return -EINVAL;
0066 break;
0067 case POWER_SUPPLY_PROP_VOLTAGE_MIN:
0068 if (info->min_voltage >= 0)
0069 val->intval = info->min_voltage;
0070 else
0071 return -EINVAL;
0072 break;
0073 case POWER_SUPPLY_PROP_PRESENT:
0074 val->intval = 1;
0075 break;
0076 default:
0077 return -EINVAL;
0078 }
0079
0080 return 0;
0081 }
0082
0083 static void z2_batt_ext_power_changed(struct power_supply *batt_ps)
0084 {
0085 struct z2_charger *charger = power_supply_get_drvdata(batt_ps);
0086
0087 schedule_work(&charger->bat_work);
0088 }
0089
0090 static void z2_batt_update(struct z2_charger *charger)
0091 {
0092 int old_status = charger->bat_status;
0093
0094 mutex_lock(&charger->work_lock);
0095
0096 charger->bat_status = charger->charge_gpiod ?
0097 (gpiod_get_value(charger->charge_gpiod) ?
0098 POWER_SUPPLY_STATUS_CHARGING :
0099 POWER_SUPPLY_STATUS_DISCHARGING) :
0100 POWER_SUPPLY_STATUS_UNKNOWN;
0101
0102 if (old_status != charger->bat_status) {
0103 pr_debug("%s: %i -> %i\n", charger->batt_ps->desc->name,
0104 old_status,
0105 charger->bat_status);
0106 power_supply_changed(charger->batt_ps);
0107 }
0108
0109 mutex_unlock(&charger->work_lock);
0110 }
0111
0112 static void z2_batt_work(struct work_struct *work)
0113 {
0114 struct z2_charger *charger;
0115 charger = container_of(work, struct z2_charger, bat_work);
0116 z2_batt_update(charger);
0117 }
0118
0119 static irqreturn_t z2_charge_switch_irq(int irq, void *devid)
0120 {
0121 struct z2_charger *charger = devid;
0122 schedule_work(&charger->bat_work);
0123 return IRQ_HANDLED;
0124 }
0125
0126 static int z2_batt_ps_init(struct z2_charger *charger, int props)
0127 {
0128 int i = 0;
0129 enum power_supply_property *prop;
0130 struct z2_battery_info *info = charger->info;
0131
0132 if (charger->charge_gpiod)
0133 props++;
0134 if (info->batt_tech >= 0)
0135 props++;
0136 if (info->batt_I2C_reg >= 0)
0137 props++;
0138 if (info->max_voltage >= 0)
0139 props++;
0140 if (info->min_voltage >= 0)
0141 props++;
0142
0143 prop = kcalloc(props, sizeof(*prop), GFP_KERNEL);
0144 if (!prop)
0145 return -ENOMEM;
0146
0147 prop[i++] = POWER_SUPPLY_PROP_PRESENT;
0148 if (charger->charge_gpiod)
0149 prop[i++] = POWER_SUPPLY_PROP_STATUS;
0150 if (info->batt_tech >= 0)
0151 prop[i++] = POWER_SUPPLY_PROP_TECHNOLOGY;
0152 if (info->batt_I2C_reg >= 0)
0153 prop[i++] = POWER_SUPPLY_PROP_VOLTAGE_NOW;
0154 if (info->max_voltage >= 0)
0155 prop[i++] = POWER_SUPPLY_PROP_VOLTAGE_MAX;
0156 if (info->min_voltage >= 0)
0157 prop[i++] = POWER_SUPPLY_PROP_VOLTAGE_MIN;
0158
0159 if (!info->batt_name) {
0160 dev_info(&charger->client->dev,
0161 "Please consider setting proper battery "
0162 "name in platform definition file, falling "
0163 "back to name \" Z2_DEFAULT_NAME \"\n");
0164 charger->batt_ps_desc.name = Z2_DEFAULT_NAME;
0165 } else
0166 charger->batt_ps_desc.name = info->batt_name;
0167
0168 charger->batt_ps_desc.properties = prop;
0169 charger->batt_ps_desc.num_properties = props;
0170 charger->batt_ps_desc.type = POWER_SUPPLY_TYPE_BATTERY;
0171 charger->batt_ps_desc.get_property = z2_batt_get_property;
0172 charger->batt_ps_desc.external_power_changed =
0173 z2_batt_ext_power_changed;
0174 charger->batt_ps_desc.use_for_apm = 1;
0175
0176 return 0;
0177 }
0178
0179 static int z2_batt_probe(struct i2c_client *client,
0180 const struct i2c_device_id *id)
0181 {
0182 int ret = 0;
0183 int props = 1;
0184 struct z2_charger *charger;
0185 struct z2_battery_info *info = client->dev.platform_data;
0186 struct power_supply_config psy_cfg = {};
0187
0188 if (info == NULL) {
0189 dev_err(&client->dev,
0190 "Please set platform device platform_data"
0191 " to a valid z2_battery_info pointer!\n");
0192 return -EINVAL;
0193 }
0194
0195 charger = kzalloc(sizeof(*charger), GFP_KERNEL);
0196 if (charger == NULL)
0197 return -ENOMEM;
0198
0199 charger->bat_status = POWER_SUPPLY_STATUS_UNKNOWN;
0200 charger->info = info;
0201 charger->client = client;
0202 i2c_set_clientdata(client, charger);
0203 psy_cfg.drv_data = charger;
0204
0205 mutex_init(&charger->work_lock);
0206
0207 charger->charge_gpiod = devm_gpiod_get_optional(&client->dev,
0208 NULL, GPIOD_IN);
0209 if (IS_ERR(charger->charge_gpiod))
0210 return dev_err_probe(&client->dev,
0211 PTR_ERR(charger->charge_gpiod),
0212 "failed to get charge GPIO\n");
0213
0214 if (charger->charge_gpiod) {
0215 gpiod_set_consumer_name(charger->charge_gpiod, "BATT CHRG");
0216
0217 irq_set_irq_type(gpiod_to_irq(charger->charge_gpiod),
0218 IRQ_TYPE_EDGE_BOTH);
0219 ret = request_irq(gpiod_to_irq(charger->charge_gpiod),
0220 z2_charge_switch_irq, 0,
0221 "AC Detect", charger);
0222 if (ret)
0223 goto err;
0224 }
0225
0226 ret = z2_batt_ps_init(charger, props);
0227 if (ret)
0228 goto err3;
0229
0230 INIT_WORK(&charger->bat_work, z2_batt_work);
0231
0232 charger->batt_ps = power_supply_register(&client->dev,
0233 &charger->batt_ps_desc,
0234 &psy_cfg);
0235 if (IS_ERR(charger->batt_ps)) {
0236 ret = PTR_ERR(charger->batt_ps);
0237 goto err4;
0238 }
0239
0240 schedule_work(&charger->bat_work);
0241
0242 return 0;
0243
0244 err4:
0245 kfree(charger->batt_ps_desc.properties);
0246 err3:
0247 if (charger->charge_gpiod)
0248 free_irq(gpiod_to_irq(charger->charge_gpiod), charger);
0249 err:
0250 kfree(charger);
0251 return ret;
0252 }
0253
0254 static int z2_batt_remove(struct i2c_client *client)
0255 {
0256 struct z2_charger *charger = i2c_get_clientdata(client);
0257
0258 cancel_work_sync(&charger->bat_work);
0259 power_supply_unregister(charger->batt_ps);
0260
0261 kfree(charger->batt_ps_desc.properties);
0262 if (charger->charge_gpiod)
0263 free_irq(gpiod_to_irq(charger->charge_gpiod), charger);
0264
0265 kfree(charger);
0266
0267 return 0;
0268 }
0269
0270 #ifdef CONFIG_PM
0271 static int z2_batt_suspend(struct device *dev)
0272 {
0273 struct i2c_client *client = to_i2c_client(dev);
0274 struct z2_charger *charger = i2c_get_clientdata(client);
0275
0276 flush_work(&charger->bat_work);
0277 return 0;
0278 }
0279
0280 static int z2_batt_resume(struct device *dev)
0281 {
0282 struct i2c_client *client = to_i2c_client(dev);
0283 struct z2_charger *charger = i2c_get_clientdata(client);
0284
0285 schedule_work(&charger->bat_work);
0286 return 0;
0287 }
0288
0289 static const struct dev_pm_ops z2_battery_pm_ops = {
0290 .suspend = z2_batt_suspend,
0291 .resume = z2_batt_resume,
0292 };
0293
0294 #define Z2_BATTERY_PM_OPS (&z2_battery_pm_ops)
0295
0296 #else
0297 #define Z2_BATTERY_PM_OPS (NULL)
0298 #endif
0299
0300 static const struct i2c_device_id z2_batt_id[] = {
0301 { "aer915", 0 },
0302 { }
0303 };
0304 MODULE_DEVICE_TABLE(i2c, z2_batt_id);
0305
0306 static struct i2c_driver z2_batt_driver = {
0307 .driver = {
0308 .name = "z2-battery",
0309 .pm = Z2_BATTERY_PM_OPS
0310 },
0311 .probe = z2_batt_probe,
0312 .remove = z2_batt_remove,
0313 .id_table = z2_batt_id,
0314 };
0315 module_i2c_driver(z2_batt_driver);
0316
0317 MODULE_LICENSE("GPL");
0318 MODULE_AUTHOR("Peter Edwards <sweetlilmre@gmail.com>");
0319 MODULE_DESCRIPTION("Zipit Z2 battery driver");