0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/delay.h>
0009 #include <linux/i2c.h>
0010 #include <linux/mfd/core.h>
0011 #include <linux/module.h>
0012 #include <linux/of_device.h>
0013 #include <linux/reboot.h>
0014 #include <linux/regmap.h>
0015
0016 #define A500_EC_I2C_ERR_TIMEOUT 500
0017 #define A500_EC_POWER_CMD_TIMEOUT 1000
0018
0019
0020
0021
0022
0023 #define CMD_SHUTDOWN 0x0
0024 #define CMD_WARM_REBOOT 0x0
0025 #define CMD_COLD_REBOOT 0x1
0026
0027 enum {
0028 REG_CURRENT_NOW = 0x03,
0029 REG_SHUTDOWN = 0x52,
0030 REG_WARM_REBOOT = 0x54,
0031 REG_COLD_REBOOT = 0x55,
0032 };
0033
0034 static struct i2c_client *a500_ec_client_pm_off;
0035
0036 static int a500_ec_read(void *context, const void *reg_buf, size_t reg_size,
0037 void *val_buf, size_t val_sizel)
0038 {
0039 struct i2c_client *client = context;
0040 unsigned int reg, retries = 5;
0041 u16 *ret_val = val_buf;
0042 s32 ret = 0;
0043
0044 reg = *(u8 *)reg_buf;
0045
0046 while (retries-- > 0) {
0047 ret = i2c_smbus_read_word_data(client, reg);
0048 if (ret >= 0)
0049 break;
0050
0051 msleep(A500_EC_I2C_ERR_TIMEOUT);
0052 }
0053
0054 if (ret < 0) {
0055 dev_err(&client->dev, "read 0x%x failed: %d\n", reg, ret);
0056 return ret;
0057 }
0058
0059 *ret_val = ret;
0060
0061 if (reg == REG_CURRENT_NOW)
0062 fsleep(10000);
0063
0064 return 0;
0065 }
0066
0067 static int a500_ec_write(void *context, const void *data, size_t count)
0068 {
0069 struct i2c_client *client = context;
0070 unsigned int reg, val, retries = 5;
0071 s32 ret = 0;
0072
0073 reg = *(u8 *)(data + 0);
0074 val = *(u16 *)(data + 1);
0075
0076 while (retries-- > 0) {
0077 ret = i2c_smbus_write_word_data(client, reg, val);
0078 if (ret >= 0)
0079 break;
0080
0081 msleep(A500_EC_I2C_ERR_TIMEOUT);
0082 }
0083
0084 if (ret < 0) {
0085 dev_err(&client->dev, "write 0x%x failed: %d\n", reg, ret);
0086 return ret;
0087 }
0088
0089 return 0;
0090 }
0091
0092 static const struct regmap_config a500_ec_regmap_config = {
0093 .name = "KB930",
0094 .reg_bits = 8,
0095 .val_bits = 16,
0096 .max_register = 0xff,
0097 };
0098
0099 static const struct regmap_bus a500_ec_regmap_bus = {
0100 .reg_format_endian_default = REGMAP_ENDIAN_NATIVE,
0101 .val_format_endian_default = REGMAP_ENDIAN_LITTLE,
0102 .write = a500_ec_write,
0103 .read = a500_ec_read,
0104 .max_raw_read = 2,
0105 };
0106
0107 static void a500_ec_poweroff(void)
0108 {
0109 i2c_smbus_write_word_data(a500_ec_client_pm_off,
0110 REG_SHUTDOWN, CMD_SHUTDOWN);
0111
0112 mdelay(A500_EC_POWER_CMD_TIMEOUT);
0113 }
0114
0115 static int a500_ec_restart_notify(struct notifier_block *this,
0116 unsigned long reboot_mode, void *data)
0117 {
0118 if (reboot_mode == REBOOT_WARM)
0119 i2c_smbus_write_word_data(a500_ec_client_pm_off,
0120 REG_WARM_REBOOT, CMD_WARM_REBOOT);
0121 else
0122 i2c_smbus_write_word_data(a500_ec_client_pm_off,
0123 REG_COLD_REBOOT, CMD_COLD_REBOOT);
0124
0125 mdelay(A500_EC_POWER_CMD_TIMEOUT);
0126
0127 return NOTIFY_DONE;
0128 }
0129
0130 static struct notifier_block a500_ec_restart_handler = {
0131 .notifier_call = a500_ec_restart_notify,
0132 .priority = 200,
0133 };
0134
0135 static const struct mfd_cell a500_ec_cells[] = {
0136 { .name = "acer-a500-iconia-battery", },
0137 { .name = "acer-a500-iconia-leds", },
0138 };
0139
0140 static int a500_ec_probe(struct i2c_client *client)
0141 {
0142 struct regmap *regmap;
0143 int err;
0144
0145 regmap = devm_regmap_init(&client->dev, &a500_ec_regmap_bus,
0146 client, &a500_ec_regmap_config);
0147 if (IS_ERR(regmap))
0148 return PTR_ERR(regmap);
0149
0150 err = devm_mfd_add_devices(&client->dev, PLATFORM_DEVID_AUTO,
0151 a500_ec_cells, ARRAY_SIZE(a500_ec_cells),
0152 NULL, 0, NULL);
0153 if (err) {
0154 dev_err(&client->dev, "failed to add sub-devices: %d\n", err);
0155 return err;
0156 }
0157
0158 if (of_device_is_system_power_controller(client->dev.of_node)) {
0159 a500_ec_client_pm_off = client;
0160
0161 err = register_restart_handler(&a500_ec_restart_handler);
0162 if (err)
0163 return err;
0164
0165 if (!pm_power_off)
0166 pm_power_off = a500_ec_poweroff;
0167 }
0168
0169 return 0;
0170 }
0171
0172 static int a500_ec_remove(struct i2c_client *client)
0173 {
0174 if (of_device_is_system_power_controller(client->dev.of_node)) {
0175 if (pm_power_off == a500_ec_poweroff)
0176 pm_power_off = NULL;
0177
0178 unregister_restart_handler(&a500_ec_restart_handler);
0179 }
0180
0181 return 0;
0182 }
0183
0184 static const struct of_device_id a500_ec_match[] = {
0185 { .compatible = "acer,a500-iconia-ec" },
0186 { }
0187 };
0188 MODULE_DEVICE_TABLE(of, a500_ec_match);
0189
0190 static struct i2c_driver a500_ec_driver = {
0191 .driver = {
0192 .name = "acer-a500-embedded-controller",
0193 .of_match_table = a500_ec_match,
0194 },
0195 .probe_new = a500_ec_probe,
0196 .remove = a500_ec_remove,
0197 };
0198 module_i2c_driver(a500_ec_driver);
0199
0200 MODULE_DESCRIPTION("Acer Iconia Tab A500 Embedded Controller driver");
0201 MODULE_AUTHOR("Dmitry Osipenko <digetx@gmail.com>");
0202 MODULE_LICENSE("GPL");