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 应用异常可以引起android系统崩溃重启
  2. Android内核学习——SearchManager分析
  3. 编译Android内核模块
  4. Android(安卓)内核与标准Linux内核的区别
  5. Android(安卓)Framework启动过程(android内核剖析笔记)
  6. android rootfs
  7. Android(安卓)Binder机制(三) ServiceManager守护进程
  8. Android(安卓)不支持 SYSV IPC (SYSV IPC)
  9. 在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程

随机推荐

  1. Android(安卓)三种方式实现圆角ImageView
  2. Android: 如何实现 in_app purchase
  3. AndroidManifest.xml文件详解(uses-config
  4. android发彩信
  5. Android(安卓)api 数据的保存方式
  6. Android的第一个应用(拨打电话)
  7. 学习插画零基础在哪学?插画绘画入门教程
  8. 搭建EXTJS和STRUTS2框架(ext和struts2简
  9. JSP 获取真实IP地址的代码
  10. 不能读取TF卡不能读取的寻回法子