Android max17044平台驱动注册


#ifdef CONFIG_BATTERY_MAX17040#include static int max17043_charger_online(void){int res = 0;gpio_request(S5PV210_GPH1(6), "GPH1_6");    s3c_gpio_cfgpin(S5PV210_GPH1(6), S3C_GPIO_INPUT);    res = gpio_get_value(S5PV210_GPH1(6));gpio_free(S5PV210_GPH1(6));return res;}//static int max17043_battery_online(void)static int max17043_ac_online(void){return max17043_charger_online();}static int max17043_charger_enable(void){int res = 0;gpio_request(S5PV210_GPH0(5), "GPH0_5");    s3c_gpio_cfgpin(S5PV210_GPH0(5), S3C_GPIO_INPUT);    res = gpio_get_value(S5PV210_GPH0(5));gpio_free(S5PV210_GPH0(5));return res>0 ? 0:1;}static struct max17040_platform_data max17043_plat = {.ac_online = max17043_ac_online,//.battery_online = max17043_battery_online,.charger_online = max17043_charger_online,.charger_enable = max17043_charger_enable,};#endifstatic struct i2c_board_info smdkv210_i2c_devs0[] __initdata = {#ifdef CONFIG_BATTERY_MAX17040{ I2C_BOARD_INFO("max17043", 0x36), .platform_data = &max17043_plat},     /* MAX17043 */#endif};


在内核中配置Power supply class support中打开 Maxim MAX17040 Fuel Gauge的支持
在include/linux/max17040_battery.h中添加如下代码
struct max17040_platform_data {int (*ac_online)(void);int (*battery_online)(void);int (*charger_online)(void);int (*charger_enable)(void);};



并修改drivers/power/max17040_battery.c

#define MAX17040_VCELL_MSB0x02#define MAX17040_VCELL_LSB0x03#define MAX17040_SOC_MSB0x04#define MAX17040_SOC_LSB0x05#define MAX17040_MODE_MSB0x06#define MAX17040_MODE_LSB0x07#define MAX17040_VER_MSB0x08#define MAX17040_VER_LSB0x09#define MAX17040_RCOMP_MSB0x0C#define MAX17040_RCOMP_LSB0x0D#define MAX17040_CMD_MSB0xFE#define MAX17040_CMD_LSB0xFF#define MAX17040_DELAY1000#define MAX17040_BATTERY_FULL95#undef _DPRINT_#ifdef _DPRINT_#define dprint(fmt, arg...) printk(fmt, ##arg)#else#define dprint(fmt, arg...)#endifstruct max17040_chip {struct i2c_client*client;struct delayed_workwork;struct power_supplybattery;struct power_supplyac;//struct power_supplyusb;struct max17040_platform_data*pdata;/* State Of Connect */int online;/* battery voltage */int vcell;/* battery capacity */int soc;/* State Of Charge */int status;int ac_online;};static int max17040_get_property(struct power_supply *psy,    enum power_supply_property psp,    union power_supply_propval *val){struct max17040_chip *chip = container_of(psy,struct max17040_chip, battery);switch (psp) {case POWER_SUPPLY_PROP_STATUS:val->intval = chip->status;break;case POWER_SUPPLY_PROP_ONLINE:val->intval = chip->online;break;case POWER_SUPPLY_PROP_VOLTAGE_NOW:val->intval = chip->vcell;break;case POWER_SUPPLY_PROP_CAPACITY:val->intval = chip->soc;break;default:return -EINVAL;}return 0;}static int ac_get_property(struct power_supply *psy,    enum power_supply_property psp,    union power_supply_propval *val){struct max17040_chip *chip = container_of(psy,struct max17040_chip, ac);switch (psp) {case POWER_SUPPLY_PROP_STATUS:val->intval = chip->status;break;case POWER_SUPPLY_PROP_ONLINE:val->intval = chip->ac_online;break;case POWER_SUPPLY_PROP_VOLTAGE_NOW:val->intval = chip->vcell;break;case POWER_SUPPLY_PROP_CAPACITY:val->intval = chip->soc;break;default:return -EINVAL;}return 0;}static int max17040_write_reg(struct i2c_client *client, int reg, u8 value){int ret;ret = i2c_smbus_write_byte_data(client, reg, value);if (ret < 0)dev_err(&client->dev, "%s: err %d\n", __func__, ret);return ret;}static int max17040_read_reg(struct i2c_client *client, int reg){int ret;ret = i2c_smbus_read_byte_data(client, reg);if (ret < 0)dev_err(&client->dev, "%s: err %d\n", __func__, ret);return ret;}static void max17040_reset(struct i2c_client *client){max17040_write_reg(client, MAX17040_CMD_MSB, 0x54);max17040_write_reg(client, MAX17040_CMD_LSB, 0x00);max17040_write_reg(client, MAX17040_RCOMP_MSB, 0x97);max17040_write_reg(client, MAX17040_RCOMP_LSB, 0x30);}static void max17040_get_vcell(struct i2c_client *client){struct max17040_chip *chip = i2c_get_clientdata(client);u8 msb;u8 lsb;msb = max17040_read_reg(client, MAX17040_VCELL_MSB);lsb = max17040_read_reg(client, MAX17040_VCELL_LSB);//chip->vcell = (msb << 4) + (lsb >> 4);chip->vcell = (((msb << 4) + (lsb >> 4)) * 25 ) / 10;dprint("*%s(): vcell 0x%04x Vcc = %d mV\n", __func__, chip->vcell, (chip->vcell * 25)/10);}static void max17040_get_soc(struct i2c_client *client){struct max17040_chip *chip = i2c_get_clientdata(client);u8 msb;u8 lsb;msb = max17040_read_reg(client, MAX17040_SOC_MSB);lsb = max17040_read_reg(client, MAX17040_SOC_LSB);chip->soc = (msb<<8) + lsb;dprint("*%s(): msb 0x%02x lsb 0x%02x\n", __func__, msb, lsb);}static void max17040_get_version(struct i2c_client *client){u8 msb;u8 lsb;msb = max17040_read_reg(client, MAX17040_VER_MSB);lsb = max17040_read_reg(client, MAX17040_VER_LSB);dprint("*%s(): msb 0x%02x lsb 0x%02x\n", __func__, msb, lsb);dev_info(&client->dev, "MAX17040 Fuel-Gauge Ver %d%d\n", msb, lsb);}static void max17040_get_online(struct i2c_client *client){struct max17040_chip *chip = i2c_get_clientdata(client);if (chip->pdata->battery_online)chip->online = chip->pdata->battery_online();elsechip->online = 1;}static void max17040_get_ac_online(struct i2c_client *client){struct max17040_chip *chip = i2c_get_clientdata(client);if (chip->pdata->ac_online)chip->ac_online = chip->pdata->ac_online();elsechip->online = 1;}static void max17040_get_status(struct i2c_client *client){struct max17040_chip *chip = i2c_get_clientdata(client);if (!chip->pdata->charger_online || !chip->pdata->charger_enable) {chip->status = POWER_SUPPLY_STATUS_UNKNOWN;return;}if (chip->pdata->charger_online()) {if (chip->pdata->charger_enable())chip->status = POWER_SUPPLY_STATUS_CHARGING;elsechip->status = POWER_SUPPLY_STATUS_NOT_CHARGING;} else {chip->status = POWER_SUPPLY_STATUS_DISCHARGING;}if (chip->soc > MAX17040_BATTERY_FULL)chip->status = POWER_SUPPLY_STATUS_FULL;}static void max17040_work(struct work_struct *work){struct max17040_chip *chip;int old_online, old_ac_online, old_vcell, old_soc;chip = container_of(work, struct max17040_chip, work.work);old_ac_online = chip->ac_online;old_online = chip->online;//old_usb_online = chip->usb_online;old_vcell = chip->vcell;old_soc = chip->soc;max17040_get_vcell(chip->client);max17040_get_soc(chip->client);max17040_get_online(chip->client);max17040_get_ac_online(chip->client);max17040_get_status(chip->client);if ((old_vcell != chip->vcell) || (old_soc != chip->soc)) {//(3)、如果电池信息有变化,就上报系统;/* printk(KERN_DEBUG "power_supply_changed for battery\n"); */power_supply_changed(&chip->battery);}#if 0//#if !defined(CONFIG_CHARGER_PM2301)//(4)、如果用PM2301充电IC,USB充电功能不用;if (old_usb_online != chip->usb_online) {/* printk(KERN_DEBUG "power_supply_changed for usb\n"); */power_supply_changed(&chip->usb);}#endifif (old_online != chip->online) {//(5)、如果有DC插入,则更新充电状态;power_supply_changed(&chip->battery);}if (old_ac_online != chip->ac_online) {power_supply_changed(&chip->ac);}schedule_delayed_work(&chip->work, MAX17040_DELAY);}static enum power_supply_property max17040_battery_props[] = {POWER_SUPPLY_PROP_STATUS,POWER_SUPPLY_PROP_ONLINE,POWER_SUPPLY_PROP_VOLTAGE_NOW,POWER_SUPPLY_PROP_CAPACITY,};static enum power_supply_property ac_adapter_props[] = {POWER_SUPPLY_PROP_STATUS,POWER_SUPPLY_PROP_ONLINE,POWER_SUPPLY_PROP_VOLTAGE_NOW,POWER_SUPPLY_PROP_CAPACITY,};static int __devinit max17040_probe(struct i2c_client *client,const struct i2c_device_id *id){struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);struct max17040_chip *chip;int ret;dprint("+%s()\n", __func__);if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))return -EIO;chip = kzalloc(sizeof(*chip), GFP_KERNEL);if (!chip)return -ENOMEM;chip->client = client;chip->pdata = client->dev.platform_data;i2c_set_clientdata(client, chip);chip->battery.name= "battery";chip->battery.type= POWER_SUPPLY_TYPE_BATTERY;chip->battery.get_property= max17040_get_property;chip->battery.properties= max17040_battery_props;chip->battery.num_properties= ARRAY_SIZE(max17040_battery_props);ret = power_supply_register(&client->dev, &chip->battery);if (ret) {dev_err(&client->dev, "failed: power supply register\n");kfree(chip);return ret;}chip->ac.name= "ac";chip->ac.type= POWER_SUPPLY_TYPE_MAINS;chip->ac.get_property= ac_get_property;chip->ac.properties= ac_adapter_props;chip->ac.num_properties= ARRAY_SIZE(ac_adapter_props);chip->ac.external_power_changed = NULL;ret = power_supply_register(&client->dev, &chip->ac);if (ret) {dev_err(&client->dev, "failed: power supply register\n");power_supply_unregister(&chip->battery);kfree(chip);return ret;}max17040_reset(client);max17040_get_version(client);INIT_DELAYED_WORK_DEFERRABLE(&chip->work, max17040_work);schedule_delayed_work(&chip->work, MAX17040_DELAY);//for(;;)ret = max17040_read_reg(client, MAX17040_VER_LSB);dprint("-%s()\n", __func__);return 0;}static int __devexit max17040_remove(struct i2c_client *client){struct max17040_chip *chip = i2c_get_clientdata(client);power_supply_unregister(&chip->battery);cancel_delayed_work(&chip->work);kfree(chip);return 0;}#ifdef CONFIG_PMstatic int max17040_suspend(struct i2c_client *client,pm_message_t state){struct max17040_chip *chip = i2c_get_clientdata(client);cancel_delayed_work(&chip->work);return 0;}static int max17040_resume(struct i2c_client *client){struct max17040_chip *chip = i2c_get_clientdata(client);schedule_delayed_work(&chip->work, MAX17040_DELAY);return 0;}#else#define max17040_suspend NULL#define max17040_resume NULL#endif /* CONFIG_PM */static const struct i2c_device_id max17040_id[] = {{ "max17040", 0 },{ "max17043", 0 },{ }};MODULE_DEVICE_TABLE(i2c, max17040_id);static struct i2c_driver max17040_i2c_driver = {.driver= {.name= "max17040",},.probe= max17040_probe,.remove= __devexit_p(max17040_remove),.suspend= max17040_suspend,.resume= max17040_resume,.id_table= max17040_id,};static int __init max17040_init(void){return i2c_add_driver(&max17040_i2c_driver);}module_init(max17040_init);static void __exit max17040_exit(void){i2c_del_driver(&max17040_i2c_driver);}module_exit(max17040_exit);MODULE_AUTHOR("Minkyu Kang ");MODULE_DESCRIPTION("MAX17040 Fuel Gauge");MODULE_LICENSE("GPL");


更多相关文章

  1. Android 内核与标准Linux内核的区别
  2. Android内核学习——SearchManager分析
  3. Android Framework启动过程(android内核剖析笔记)
  4. Android基于腾讯X5内核的WebView(超级浏览器)
  5. Android 内核相关内容总结

随机推荐

  1. Android帧率测试
  2. Android中判断字符串中必须包含字母或者
  3. Android(安卓)SDK R17
  4. 配置Qt Creator for Android
  5. Android(安卓)Selector和Shape的使用方法
  6. android ListView中添加ImageButton按钮
  7. Android(安卓)下的图片选择与裁剪开源库
  8. Android(安卓)布局 之 LinearLayout
  9. android图片压缩的3种方法实例
  10. android api (83) —— InputMethodSessi