Introduce Embedded Controller driver for Acer A500
Subsystems (4)
v5 cover Introduce Embedded Controller driver for Acer A500
Hello!
This series adds support for the Embedded Controller which is found on Acer Iconia Tab A500 (Android tablet device).
The Embedded Controller is ENE KB930 and it's running firmware customized for the A500. The firmware interface may be reused by some other sibling Acer tablets, although none of those tablets are supported in upstream yet.
Changelog:
v5: - No changes. Re-sending again in order to check whether dtschema-bot
warning is resolved now, which didn't happen in v4 because bot used older 5.9 kernel code base instead of 5.10.
v4: - No code changes. Added r-b from Rob Herring and Sebastian Reichel.
Re-sending for 5.11.
- The v3 of LED driver was applied by Pavel Machek and already presents
in v5.10 kernel.v3: - Rebased on a recent linux-next. Fixed new merge conflict and dropped
"regmap: Use flexible sleep" patch because it's already applied.
v2: - Factored out KB930 device-tree binding into a separate file, like it
was suggested by Lubomir Rintel.
- Switched to use regmap API like it was suggested by Lubomir Rintel.
- Added patch "regmap: Use flexible sleep" which allows not to hog CPU while LED is switching state.
- Corrected MODULE_LICENSE to use "GPL" in all patches.
- Corrected MFD driver Kconfig entry like it was suggested by Lubomir Rintel, it now depends on I2C.
- Switched to use I2C probe_new() in the MFD driver.
- Renamed the global pm_off variable, like it was suggested by Lubomir Rintel and Lee Jones.
- Dropped serial number from the battery driver because I realized that it's not a battery serial, but a device serial.
- Battery driver now uses dev_err_probe(), like it was suggested by Sebastian Reichel.
- Dropped legacy LED_ON usage from the LED driver and renamed the LEDs, like it was suggested by Pavel Machek. I also checked whether LED-name customization via device-tree could be needed by other potentially compatible devices and it shouldn't be needed, anyways it won't be difficult to extend the code even if I'm wrong.
Dmitry Osipenko (4):
dt-bindings: mfd: Add ENE KB930 Embedded Controller binding
mfd: Add driver for Embedded Controller found on Acer Iconia Tab A500
power: supply: Add battery gauge driver for Acer Iconia Tab A500
ARM: tegra: acer-a500: Add Embedded Controller
.../devicetree/bindings/mfd/ene-kb930.yaml | 66 ++++ .../boot/dts/tegra20-acer-a500-picasso.dts | 17 + drivers/mfd/Kconfig | 12 + drivers/mfd/Makefile | 1 + drivers/mfd/acer-ec-a500.c | 203 ++++++++++++ drivers/power/supply/Kconfig | 6 + drivers/power/supply/Makefile | 1 + drivers/power/supply/acer_a500_battery.c | 297 ++++++++++++++++++ 8 files changed, 603 insertions(+) create mode 100644 Documentation/devicetree/bindings/mfd/ene-kb930.yaml create mode 100644 drivers/mfd/acer-ec-a500.c create mode 100644 drivers/power/supply/acer_a500_battery.c
Signature · 1 line
2.27.0
PATCH v5 1/4 dt-bindings: mfd: Add ENE KB930 Embedded Controller binding
Add binding document for the ENE KB930 Embedded Controller.
--- .../devicetree/bindings/mfd/ene-kb930.yaml | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 Documentation/devicetree/bindings/mfd/ene-kb930.yaml
Documentation/devicetree/bindings/mfd/ene-kb930.yaml new file +66 -0
@@ -0,0 +1,66 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mfd/ene-kb930.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ENE KB930 Embedded Controller bindings + +description: | + This binding describes the ENE KB930 Embedded Controller attached to an + I2C bus. + +maintainers: + - Dmitry Osipenko <[email protected]> + +properties: + compatible: + items: + - enum: + - acer,a500-iconia-ec # Acer A500 Iconia tablet device + - enum: + - ene,kb930 + reg: + maxItems: 1 + + monitored-battery: true + power-supplies: true + system-power-controller: true + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + battery: battery-cell { + compatible = "simple-battery"; + charge-full-design-microamp-hours = <3260000>; + energy-full-design-microwatt-hours = <24000000>; + operating-range-celsius = <0 40>; + }; + + mains: ac-adapter { + compatible = "gpio-charger"; + charger-type = "mains"; + gpios = <&gpio 125 0>; + }; + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + embedded-controller@58 { + compatible = "acer,a500-iconia-ec", "ene,kb930"; + reg = <0x58>; + + system-power-controller; + + monitored-battery = <&battery>; + power-supplies = <&mains>; + }; + }; + +...
Signature · 1 line
2.27.0
Rob Herring
maintainerRe: [PATCH v5 1/4] dt-bindings: mfd: Add ENE KB930 Embedded Controller binding
Quoted 9 lines · Dmitry Osipenko
Add binding document for the ENE KB930 Embedded Controller.
Reviewed-by Rob Herring <[email protected]>Signed-off-by Dmitry Osipenko <[email protected]>--- .../devicetree/bindings/mfd/ene-kb930.yaml | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 Documentation/devicetree/bindings/mfd/ene-kb930.yaml
My bot found errors running 'make dt_binding_check' on your patch:
yamllint warnings/errors:./Documentation/devicetree/bindings/mfd/ene-kb930.yaml:20:9: [warning] wrong indentation: expected 10 but found 8 (indentation) ./Documentation/devicetree/bindings/mfd/ene-kb930.yaml:22:9: [warning] wrong indentation: expected 10 but found 8 (indentation)
dtschema/dtc warnings/errors:
See https://patchwork.ozlabs.org/patch/1394517
The base for the patch is generally the last rc1. Any dependencies should be noted.
If you already ran 'make dt_binding_check' and didn't see the above error(s), then make sure 'yamllint' is installed and dt-schema is up to date:
pip3 install dtschema --upgrade
Please check and re-submit.
PATCH v5 2/4 mfd: Add driver for Embedded Controller found on Acer Iconia Tab A500
In reply to Dmitry OsipenkoAcer Iconia Tab A500 is an Android tablet device, it has ENE KB930 Embedded Controller which provides battery-gauge, LED, GPIO and some other functions. The EC uses firmware that is specifically customized for Acer A500. This patch adds MFD driver for the Embedded Controller which allows to power-off / reboot the A500 device, it also provides a common register read/write API that will be used by the sub-devices.
--- drivers/mfd/Kconfig | 12 +++ drivers/mfd/Makefile | 1 + drivers/mfd/acer-ec-a500.c | 203 +++++++++++++++++++++++++++++++++++++ 3 files changed, 216 insertions(+) create mode 100644 drivers/mfd/acer-ec-a500.c
drivers/mfd/Kconfig +12 -0
@@ -2097,6 +2097,18 @@ config MFD_KHADAS_MCU additional drivers must be enabled in order to use the functionality of the device. +config MFD_ACER_A500_EC + tristate "Embedded Controller driver for Acer Iconia Tab A500" + depends on I2C + depends on ARCH_TEGRA_2x_SOC || COMPILE_TEST + select MFD_CORE + select REGMAP + help + Support for Acer Iconia Tab A500 Embedded Controller. + + The controller itself is ENE KB930, it is running firmware + customized for the specific needs of the Acer A500 hardware. + menu "Multimedia Capabilities Port drivers" depends on ARCH_SA1100
drivers/mfd/Makefile +1 -0
@@ -263,6 +263,7 @@ obj-$(CONFIG_MFD_ROHM_BD71828) += rohm-bd71828.o obj-$(CONFIG_MFD_ROHM_BD718XX) += rohm-bd718x7.o obj-$(CONFIG_MFD_STMFX) += stmfx.o obj-$(CONFIG_MFD_KHADAS_MCU) += khadas-mcu.o +obj-$(CONFIG_MFD_ACER_A500_EC) += acer-ec-a500.o obj-$(CONFIG_SGI_MFD_IOC3) += ioc3.o obj-$(CONFIG_MFD_SIMPLE_MFD_I2C) += simple-mfd-i2c.o
drivers/mfd/acer-ec-a500.c new file +203 -0
203 lines not on this page · raw message
Signature · 1 line
2.27.0
Re: [PATCH v5 2/4] mfd: Add driver for Embedded Controller found on Acer Iconia Tab A500
Quoted 20 lines · Dmitry Osipenko
Acer Iconia Tab A500 is an Android tablet device, it has ENE KB930 Embedded Controller which provides battery-gauge, LED, GPIO and some other functions. The EC uses firmware that is specifically customized for Acer A500. This patch adds MFD driver for the Embedded Controller which allows to power-off / reboot the A500 device, it also provides a common register read/write API that will be used by the sub-devices.
Signed-off-by Dmitry Osipenko <[email protected]>--- drivers/mfd/Kconfig | 12 +++ drivers/mfd/Makefile | 1 + drivers/mfd/acer-ec-a500.c | 203 +++++++++++++++++++++++++++++++++++++ 3 files changed, 216 insertions(+) create mode 100644 drivers/mfd/acer-ec-a500.cdrivers/mfd/Kconfig +0
-0
drivers/mfd/Kconfig config MFD_KHADAS_MCU · line 2101
Quoted 5 lines
drivers/mfd/Kconfig +2
-0@@ -2097,6 +2097,18 @@ config MFD_KHADAS_MCU additional drivers must be enabled in order to use the functionality of the device. +config MFD_ACER_A500_EC + tristate "Embedded Controller driver for Acer Iconia Tab A500"
Drop "driver". This is meant to be describing the device.
drivers/mfd/Kconfig config MFD_KHADAS_MCU · line 2102
Quoted 1 line
drivers/mfd/Kconfig +1
-0+ depends on I2C
depends on OF ?
Quoted 30 lines
drivers/mfd/Kconfig +9
-0+ depends on ARCH_TEGRA_2x_SOC || COMPILE_TEST + select MFD_CORE + select REGMAP + help + Support for Acer Iconia Tab A500 Embedded Controller. + + The controller itself is ENE KB930, it is running firmware + customized for the specific needs of the Acer A500 hardware. + menu "Multimedia Capabilities Port drivers" depends on ARCH_SA1100drivers/mfd/Makefile +1
-0@@ -263,6 +263,7 @@ obj-$(CONFIG_MFD_ROHM_BD71828) += rohm-bd71828.o obj-$(CONFIG_MFD_ROHM_BD718XX) += rohm-bd718x7.o obj-$(CONFIG_MFD_STMFX) += stmfx.o obj-$(CONFIG_MFD_KHADAS_MCU) += khadas-mcu.o +obj-$(CONFIG_MFD_ACER_A500_EC) += acer-ec-a500.o obj-$(CONFIG_SGI_MFD_IOC3) += ioc3.o obj-$(CONFIG_MFD_SIMPLE_MFD_I2C) += simple-mfd-i2c.odrivers/mfd/acer-ec-a500.c new file +0
-0
drivers/mfd/acer-ec-a500.c line 3
Quoted 3 lines
drivers/mfd/acer-ec-a500.c new file +3
-0@@ -0,0 +1,203 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* +* MFD driver for Acer Iconia Tab A500 Embedded Controller.
An "MFD" isn't a thing. Please describe the device.
drivers/mfd/acer-ec-a500.c line 7
Quoted 3 lines
drivers/mfd/acer-ec-a500.c new file +3
-0+* Copyright 2020 GRATE-driver project. +* +* Based on downstream driver from Acer Inc.
Most drivers are. Not sure this is required.
drivers/mfd/acer-ec-a500.c line 16
Quoted 9 lines
drivers/mfd/acer-ec-a500.c new file +9
-0+*/ + +#include <linux/delay.h> +#include <linux/i2c.h> +#include <linux/mfd/core.h> +#include <linux/module.h> +#include <linux/of_device.h> +#include <linux/regmap.h> +#include <linux/reboot.h>
Alphabetical please. ;)
Quoted 11 lines
drivers/mfd/acer-ec-a500.c new file +11
-0+#define A500_EC_I2C_ERR_TIMEOUT 500 +#define A500_EC_POWER_CMD_TIMEOUT 1000 + +enum { +REG_CURRENT_NOW =0x03 , +REG_SHUTDOWN =0x52 , +REG_WARM_REBOOT =0x54 , +REG_COLD_REBOOT =0x55 , +}; + +static struct i2c_client *a500_ec_client_pm_off;
drivers/mfd/acer-ec-a500.c line 38
Quoted 10 lines
drivers/mfd/acer-ec-a500.c new file +10
-0+ +static int a500_ec_read (void *context,const void *reg_buf,size_t reg_size, +void *val_buf,size_t val_sizel) +{ +struct i2c_client *client = context; +unsigned int reg, retries =5 ; +u16 *ret_val = val_buf; +s32 ret =0 ; + +if (reg_size !=1 || val_sizel !=2 )
No magic numbers please.
What does this *mean*?
drivers/mfd/acer-ec-a500.c line 37
Quoted 1 line
drivers/mfd/acer-ec-a500.c new file +1
-0+return -EOPNOTSUPP ;
Why EOPNOTSUPP?
Quoted 9 lines
drivers/mfd/acer-ec-a500.c new file +9
-0+ reg = *(u8 *)reg_buf; + +while (retries-- >0 ) { + ret =i2c_smbus_read_word_data (client, reg); +if (ret >=0 ) +break ; + +msleep (A500_EC_I2C_ERR_TIMEOUT ); + }
drivers/mfd/acer-ec-a500.c line 59
Quoted 10 lines
drivers/mfd/acer-ec-a500.c new file +10
-0+ +if (ret <0 ) { +dev_err (&client->dev,"read 0x%x failed: %d\n" , reg, ret); +return ret; + } + + *ret_val = ret; + +if (reg ==REG_CURRENT_NOW ) +fsleep (10000 );
Ooo, new toy!
drivers/mfd/acer-ec-a500.c line 58
Quoted 2 lines
drivers/mfd/acer-ec-a500.c new file +2
-0+return 0 ; +}
I'm surprised there isn't a generic function which does this kind of read. Seems like pretty common/boilerplate stuff.
drivers/mfd/acer-ec-a500.c line 70
Quoted 7 lines
drivers/mfd/acer-ec-a500.c new file +7
-0+static int a500_ec_write (void *context,const void *data,size_t count) +{ +struct i2c_client *client = context; +unsigned int reg, val, retries =5 ; +s32 ret =0 ; + +if (count !=3 )
Define or comment needed.
Quoted 10 lines
drivers/mfd/acer-ec-a500.c new file +10
-0+return -EOPNOTSUPP ; + + reg = *(u8 *)(data +0 ); + val = *(u16 *)(data +1 ); + +while (retries-- >0 ) { + ret =i2c_smbus_write_word_data (client, reg, val); +if (ret >=0 ) +break ; +
drivers/mfd/acer-ec-a500.c line 90
Quoted 10 lines
drivers/mfd/acer-ec-a500.c new file +10
-0+msleep (A500_EC_I2C_ERR_TIMEOUT ); + } + +if (ret <0 ) { +dev_err (&client->dev,"write 0x%x failed: %d\n" , reg, ret); +return ret; + } + +return 0 ; +}
Again, seems pretty boilerplate. Are you sure there isn't a helper?
Quoted 21 lines
drivers/mfd/acer-ec-a500.c new file +21
-0+static const struct regmap_config a500_ec_regmap_config = { + .name ="KB930" , + .reg_bits =8 , + .val_bits =16 , + .max_register =0xff , +}; + +static const struct regmap_bus a500_ec_regmap_bus = { + .reg_format_endian_default =REGMAP_ENDIAN_NATIVE , + .val_format_endian_default =REGMAP_ENDIAN_LITTLE , + .write = a500_ec_write, + .read = a500_ec_read, + .max_raw_read =2 , +}; + +static void a500_ec_poweroff (void ) +{ +i2c_smbus_write_word_data (a500_ec_client_pm_off,REG_SHUTDOWN ,0 ); + +mdelay (A500_EC_POWER_CMD_TIMEOUT ); +}
drivers/mfd/acer-ec-a500.c line 122
Quoted 10 lines
drivers/mfd/acer-ec-a500.c new file +10
-0+ +static int a500_ec_restart_notify (struct notifier_block *this, +unsigned long reboot_mode,void *data) +{ +if (reboot_mode ==REBOOT_WARM ) +i2c_smbus_write_word_data (a500_ec_client_pm_off, +REG_WARM_REBOOT ,0 ); +else +i2c_smbus_write_word_data (a500_ec_client_pm_off, +REG_COLD_REBOOT ,1 );
What's with the magic '0' and '1's at the end?
Quoted 8 lines
drivers/mfd/acer-ec-a500.c new file +8
-0+mdelay (A500_EC_POWER_CMD_TIMEOUT ); + +return NOTIFY_DONE ; +} + +static struct notifier_block a500_ec_restart_handler = { + .notifier_call = a500_ec_restart_notify, + .priority =200 ,
drivers/mfd/acer-ec-a500.c line 141
Quoted 10 lines
drivers/mfd/acer-ec-a500.c new file +10
-0+}; + +static const struct mfd_cell a500_ec_cells[] = { + { .name ="acer-a500-iconia-battery" , }, + { .name ="acer-a500-iconia-leds" , }, +}; + +static int a500_ec_probe (struct i2c_client *client) +{ +struct regmap *rmap;
'rmap' barely makes the top 10:
$ git grep -ho "struct regmap \*[a-z]*" | sort | uniq -c | sort -rn | head
1814 struct regmap *regmap
581 struct regmap *map
97 struct regmap *
50 struct regmap *syscon
50 struct regmap *r
35 struct regmap *reg
34 struct regmap *cfgchip
32 struct regmap *grf
30 struct regmap *rmap
27 struct regmap *basePlease use regmap here.
drivers/mfd/acer-ec-a500.c line 149
Quoted 8 lines
drivers/mfd/acer-ec-a500.c new file +8
-0+int err; + + rmap =devm_regmap_init (&client->dev, &a500_ec_regmap_bus, + client, &a500_ec_regmap_config); +if (IS_ERR (rmap)) +return PTR_ERR (rmap); + +/* register battery and LED sub-devices */
This comment is superfluous and is just the type of documentation that becomes out-of-date quickly.
drivers/mfd/acer-ec-a500.c line 158
Quoted 9 lines
drivers/mfd/acer-ec-a500.c new file +9
-0+ err =devm_mfd_add_devices (&client->dev,PLATFORM_DEVID_AUTO , + a500_ec_cells,ARRAY_SIZE (a500_ec_cells), +NULL ,0 ,NULL ); +if (err) { +dev_err (&client->dev,"failed to add sub-devices: %d\n" , err); +return err; + } + +/* set up power management functions */
We know what "power" and "pm" mean. You can safely remove this comment.
Quoted 45 lines
drivers/mfd/acer-ec-a500.c new file +45
-0+if (of_device_is_system_power_controller (client->dev.of_node)) { + a500_ec_client_pm_off = client; + + err =register_restart_handler (&a500_ec_restart_handler); +if (err) +return err; + +if (!pm_power_off) + pm_power_off = a500_ec_poweroff; + } + +return 0 ; +} + +static int a500_ec_remove (struct i2c_client *client) +{ +if (of_device_is_system_power_controller (client->dev.of_node)) { +if (pm_power_off == a500_ec_poweroff) + pm_power_off =NULL ; + +unregister_restart_handler (&a500_ec_restart_handler); + } + +return 0 ; +} + +static const struct of_device_id a500_ec_match[] = { + { .compatible ="acer,a500-iconia-ec" }, + { } +}; +MODULE_DEVICE_TABLE (of, a500_ec_match); + +static struct i2c_driver a500_ec_driver = { + .driver = { + .name ="acer-a500-embedded-controller" , + .of_match_table = a500_ec_match, + }, + .probe_new = a500_ec_probe, + .remove = a500_ec_remove, +}; +module_i2c_driver (a500_ec_driver); + +MODULE_DESCRIPTION ("Acer Iconia Tab A500 Embedded Controller driver" ); +MODULE_AUTHOR ("Dmitry Osipenko <[email protected]>" ); +MODULE_LICENSE ("GPL" );
Signature · 4 lines
Lee Jones [李琼斯] Senior Technical Lead - Developer Services Linaro.org │ Open source software for Arm SoCs Follow Linaro: Facebook | Twitter | Blog
Re: [PATCH v5 2/4] mfd: Add driver for Embedded Controller found on Acer Iconia Tab A500
13.11.2020 12:37, Lee Jones пишет:
...
Quoted 8 lines
drivers/mfd/Kconfig config MFD_KHADAS_MCU · line 2101
Quoted 2 lines
drivers/mfd/Kconfig +2
-0+config MFD_ACER_A500_EC + tristate "Embedded Controller driver for Acer Iconia Tab A500"Drop "driver". This is meant to be describing the device.
drivers/mfd/Kconfig config MFD_KHADAS_MCU · line 2102
Quoted 1 line
drivers/mfd/Kconfig +1
-0+ depends on I2Cdepends on OF ?
...
Quoted 4 lines
drivers/mfd/Kconfig config MFD_KHADAS_MCU · line 2106
Quoted 4 lines
drivers/mfd/Kconfig +4
-0+ depends on ARCH_TEGRA_2x_SOC || COMPILE_TEST + select MFD_CORE + select REGMAP + help
ARCH_TEGRA_2x_SOC selects OF.
For COMPILE_TEST it doesn't matter since OF framework provides stubs for !OF.
...
Quoted 12 lines
drivers/mfd/acer-ec-a500.c line 38
Quoted 9 lines
drivers/mfd/acer-ec-a500.c new file +9
-0+static int a500_ec_read (void *context,const void *reg_buf,size_t reg_size, +void *val_buf,size_t val_sizel) +{ +struct i2c_client *client = context; +unsigned int reg, retries =5 ; +u16 *ret_val = val_buf; +s32 ret =0 ; + +if (reg_size !=1 || val_sizel !=2 )No magic numbers please.
Quoted 1 line
What does this *mean*?
These are the size of address register and size of a read value, both in bytes.
Quoted 3 lines
Review
Quoted 1 line
(quoted diff) +1
-0+ return -EOPNOTSUPP;Why EOPNOTSUPP?
Other sizes aren't supported by embedded controller.
Although, perhaps this check isn't really needed at all since the sizes are already expressed in the a500_ec_regmap_config.
I'll need to take a closer look at why this size-checking was added because don't quite remember already. If it's not needed, then I'll remove it in the next revision, otherwise will add a clarifying comment.
Quoted 22 lines
Quoted 9 lines
drivers/mfd/acer-ec-a500.c new file +9
-0+ reg = *(u8 *)reg_buf; + +while (retries-- >0 ) { + ret =i2c_smbus_read_word_data (client, reg); +if (ret >=0 ) +break ; + +msleep (A500_EC_I2C_ERR_TIMEOUT ); + }drivers/mfd/acer-ec-a500.c line 59
Quoted 10 lines
drivers/mfd/acer-ec-a500.c new file +10
-0+ +if (ret <0 ) { +dev_err (&client->dev,"read 0x%x failed: %d\n" , reg, ret); +return ret; + } + + *ret_val = ret; + +if (reg ==REG_CURRENT_NOW ) +fsleep (10000 );Ooo, new toy!
Quoted 5 lines
Review
Quoted 2 lines
(quoted diff) +2
-0+ return 0; +}I'm surprised there isn't a generic function which does this kind of read. Seems like pretty common/boilerplate stuff.
I'm not quite sure that this is a really very common pattern which deserves a generic helper.
...
Quoted 11 lines
drivers/mfd/acer-ec-a500.c line 122
Quoted 9 lines
drivers/mfd/acer-ec-a500.c new file +9
-0+static int a500_ec_restart_notify (struct notifier_block *this, +unsigned long reboot_mode,void *data) +{ +if (reboot_mode ==REBOOT_WARM ) +i2c_smbus_write_word_data (a500_ec_client_pm_off, +REG_WARM_REBOOT ,0 ); +else +i2c_smbus_write_word_data (a500_ec_client_pm_off, +REG_COLD_REBOOT ,1 );What's with the magic '0' and '1's at the end?
These are the values which controller's firmware wants to see, otherwise it will reject command as invalid. I'll add a clarifying comment to the code.
Thank you for the review. I'll address all the comments in the v7.
Re: [PATCH v5 2/4] mfd: Add driver for Embedded Controller found on Acer Iconia Tab A500
Quoted 18 lines · Dmitry Osipenko
13.11.2020 12:37, Lee Jones пишет:
...Quoted 8 lines
drivers/mfd/Kconfig config MFD_KHADAS_MCU · line 2101
Quoted 2 lines
drivers/mfd/Kconfig +2
-0+config MFD_ACER_A500_EC + tristate "Embedded Controller driver for Acer Iconia Tab A500"Drop "driver". This is meant to be describing the device.
drivers/mfd/Kconfig config MFD_KHADAS_MCU · line 2102
Quoted 1 line
drivers/mfd/Kconfig +1
-0+ depends on I2Cdepends on OF ?
...
Quoted 4 lines
drivers/mfd/Kconfig config MFD_KHADAS_MCU · line 2106
Quoted 4 lines
drivers/mfd/Kconfig +4
-0+ depends on ARCH_TEGRA_2x_SOC || COMPILE_TEST + select MFD_CORE + select REGMAP + help
ARCH_TEGRA_2x_SOCselects OF.
Quoted 2 lines
For
COMPILE_TESTit doesn't matter since OF framework provides stubs for !OF.
I always thought it was best to be explicit.
Quoted 13 lines
...
Quoted 12 lines
drivers/mfd/acer-ec-a500.c line 38
Quoted 9 lines
drivers/mfd/acer-ec-a500.c new file +9
-0+static int a500_ec_read (void *context,const void *reg_buf,size_t reg_size, +void *val_buf,size_t val_sizel) +{ +struct i2c_client *client = context; +unsigned int reg, retries =5 ; +u16 *ret_val = val_buf; +s32 ret =0 ; + +if (reg_size !=1 || val_sizel !=2 )No magic numbers please.
Quoted 4 lines
Quoted 1 line
What does this *mean*?
These are the size of address register and size of a read value, both in bytes.
Great. But don't tell me that. You need to tell the next person who reads this code, and the next, and the next. Defines work best for this. Comments are also okay.
Quoted 4 lines
Quoted 3 lines
Review
Quoted 1 line
(quoted diff) +1
-0+ return -EOPNOTSUPP;Why EOPNOTSUPP?
Quoted 8 lines
Other sizes aren't supported by embedded controller.
Although, perhaps this check isn't really needed at all since the sizes are already expressed in the
a500_ec_regmap_config.I'll need to take a closer look at why this size-checking was added because don't quite remember already. If it's not needed, then I'll remove it in the next revision, otherwise will add a clarifying comment.
"Operation not supported on transport endpoint" doesn't seem like a good fit here. If the check says, please consider changing it to something like -EINVAL.
Quoted 22 lines
Quoted 22 lines
Quoted 9 lines
drivers/mfd/acer-ec-a500.c new file +9
-0+ reg = *(u8 *)reg_buf; + +while (retries-- >0 ) { + ret =i2c_smbus_read_word_data (client, reg); +if (ret >=0 ) +break ; + +msleep (A500_EC_I2C_ERR_TIMEOUT ); + }drivers/mfd/acer-ec-a500.c line 59
Quoted 10 lines
drivers/mfd/acer-ec-a500.c new file +10
-0+ +if (ret <0 ) { +dev_err (&client->dev,"read 0x%x failed: %d\n" , reg, ret); +return ret; + } + + *ret_val = ret; + +if (reg ==REG_CURRENT_NOW ) +fsleep (10000 );Ooo, new toy!
Quoted 8 lines
Quoted 5 lines
Review
Quoted 2 lines
(quoted diff) +2
-0+ return 0; +}I'm surprised there isn't a generic function which does this kind of read. Seems like pretty common/boilerplate stuff.
I'm not quite sure that this is a really very common pattern which deserves a generic helper.
What? Read from I2C a few times, then sleep sounds like a pretty common pattern to me.
Quoted 13 lines
...
Quoted 11 lines
drivers/mfd/acer-ec-a500.c line 122
Quoted 9 lines
drivers/mfd/acer-ec-a500.c new file +9
-0+static int a500_ec_restart_notify (struct notifier_block *this, +unsigned long reboot_mode,void *data) +{ +if (reboot_mode ==REBOOT_WARM ) +i2c_smbus_write_word_data (a500_ec_client_pm_off, +REG_WARM_REBOOT ,0 ); +else +i2c_smbus_write_word_data (a500_ec_client_pm_off, +REG_COLD_REBOOT ,1 );What's with the magic '0' and '1's at the end?
Quoted 3 lines
These are the values which controller's firmware wants to see, otherwise it will reject command as invalid. I'll add a clarifying comment to the code.
Thanks. Hopefully with a bit more information as to why the firmware expects to see them. Hopefully they're not random.
Signature · 4 lines
Lee Jones [李琼斯] Senior Technical Lead - Developer Services Linaro.org │ Open source software for Arm SoCs Follow Linaro: Facebook | Twitter | Blog
Re: [PATCH v5 2/4] mfd: Add driver for Embedded Controller found on Acer Iconia Tab A500
16.11.2020 11:48, Lee Jones пишет:
Quoted 16 lines
Quoted 16 lines
Quoted 8 lines
drivers/mfd/Kconfig config MFD_KHADAS_MCU · line 2101
Quoted 2 lines
drivers/mfd/Kconfig +2
-0+config MFD_ACER_A500_EC + tristate "Embedded Controller driver for Acer Iconia Tab A500"Drop "driver". This is meant to be describing the device.
drivers/mfd/Kconfig config MFD_KHADAS_MCU · line 2102
Quoted 1 line
drivers/mfd/Kconfig +1
-0+ depends on I2Cdepends on OF ?
...
Quoted 4 lines
drivers/mfd/Kconfig config MFD_KHADAS_MCU · line 2106
Quoted 4 lines
drivers/mfd/Kconfig +4
-0+ depends on ARCH_TEGRA_2x_SOC || COMPILE_TEST + select MFD_CORE + select REGMAP + help
ARCH_TEGRA_2x_SOCselects OF.
Quoted 4 lines
Quoted 2 lines
For
COMPILE_TESTit doesn't matter since OF framework provides stubs for !OF.I always thought it was best to be explicit.
Alright, I see that the OF selection is all over the MFD Kconfig, hence let's keep it consistent.
I also prefer the explicit variant more, but some other kernel maintainers may disagree.
Quoted 8 lines
Quoted 8 lines
...
Quoted 1 line
Why EOPNOTSUPP?
Other sizes aren't supported by embedded controller.
Although, perhaps this check isn't really needed at all since the sizes are already expressed in the
a500_ec_regmap_config.
Quoted 7 lines
Quoted 3 lines
I'll need to take a closer look at why this size-checking was added because don't quite remember already. If it's not needed, then I'll remove it in the next revision, otherwise will add a clarifying comment.
"Operation not supported on transport endpoint" doesn't seem like a good fit here. If the check says, please consider changing it to something like
-EINVAL.
The regmap core code performs all the necessary checks before driver's code is reached, perhaps I just overlooked something before. Hence it will be removed in the next revision.
...
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
drivers/mfd/acer-ec-a500.c new file +7
-0+while (retries-- >0 ) { + ret =i2c_smbus_read_word_data (client, reg); +if (ret >=0 ) +break ; + +msleep (A500_EC_I2C_ERR_TIMEOUT ); + }
...
Quoted 8 lines
Quoted 5 lines
Quoted 2 lines
I'm surprised there isn't a generic function which does this kind of read. Seems like pretty common/boilerplate stuff.
I'm not quite sure that this is a really very common pattern which deserves a generic helper.
What? Read from I2C a few times, then sleep sounds like a pretty common pattern to me.
Maybe the read_poll_timeout() helper could be used for that, but I think the open-coded variant is much easier to perceive, don't you agree?
Quoted 13 lines
Quoted 13 lines
...
Quoted 11 lines
drivers/mfd/acer-ec-a500.c line 122
Quoted 9 lines
drivers/mfd/acer-ec-a500.c new file +9
-0+static int a500_ec_restart_notify (struct notifier_block *this, +unsigned long reboot_mode,void *data) +{ +if (reboot_mode ==REBOOT_WARM ) +i2c_smbus_write_word_data (a500_ec_client_pm_off, +REG_WARM_REBOOT ,0 ); +else +i2c_smbus_write_word_data (a500_ec_client_pm_off, +REG_COLD_REBOOT ,1 );What's with the magic '0' and '1's at the end?
Quoted 7 lines
Quoted 3 lines
These are the values which controller's firmware wants to see, otherwise it will reject command as invalid. I'll add a clarifying comment to the code.
Thanks. Hopefully with a bit more information as to why the firmware expects to see them. Hopefully they're not random.
These are the firmware-defined specific command opcodes, I'll add defines for them to make it more clear, thanks.
Re: [PATCH v5 2/4] mfd: Add driver for Embedded Controller found on Acer Iconia Tab A500
Quoted 12 lines · Dmitry Osipenko
...
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
drivers/mfd/acer-ec-a500.c new file +7
-0+while (retries-- >0 ) { + ret =i2c_smbus_read_word_data (client, reg); +if (ret >=0 ) +break ; + +msleep (A500_EC_I2C_ERR_TIMEOUT ); + }...
Quoted 3 lines
Quoted 3 lines
Quoted 2 lines
I'm surprised there isn't a generic function which does this kind of read. Seems like pretty common/boilerplate stuff.
Quoted 8 lines
Quoted 5 lines
Quoted 2 lines
I'm not quite sure that this is a really very common pattern which deserves a generic helper.
What? Read from I2C a few times, then sleep sounds like a pretty common pattern to me.
Maybe the
read_poll_timeout()helper could be used for that, but I think the open-coded variant is much easier to perceive, don't you agree?
I haven't looked into it. My comment was more general in nature.
As a general rule, helpers are better than open coding, but there are always exceptions. There may not even be a suitable helper for this use-case. As I say, the comment was more of a passing remark.
[...]
Quoted 9 lines
Quoted 6 lines
Quoted 3 lines
These are the values which controller's firmware wants to see, otherwise it will reject command as invalid. I'll add a clarifying comment to the code.
Thanks. Hopefully with a bit more information as to why the firmware expects to see them. Hopefully they're not random.
These are the firmware-defined specific command opcodes, I'll add defines for them to make it more clear, thanks.
That'll do.
Signature · 4 lines
Lee Jones [李琼斯] Senior Technical Lead - Developer Services Linaro.org │ Open source software for Arm SoCs Follow Linaro: Facebook | Twitter | Blog
PATCH v5 3/4 power: supply: Add battery gauge driver for Acer Iconia Tab A500
In reply to Dmitry OsipenkoThis patch adds battery gauge driver for Acer Iconia Tab A500 device. The battery gauge function is provided via the Embedded Controller, which is found on the Acer A500.
--- drivers/power/supply/Kconfig | 6 + drivers/power/supply/Makefile | 1 + drivers/power/supply/acer_a500_battery.c | 297 +++++++++++++++++++++++ 3 files changed, 304 insertions(+) create mode 100644 drivers/power/supply/acer_a500_battery.c
drivers/power/supply/Kconfig +6 -0
@@ -774,4 +774,10 @@ config RN5T618_POWER This driver can also be built as a module. If so, the module will be called rn5t618_power. +config BATTERY_ACER_A500 + tristate "Acer Iconia Tab A500 battery driver" + depends on MFD_ACER_A500_EC + help + Say Y to include support for Acer Iconia Tab A500 battery fuel gauge. + endif # POWER_SUPPLY
drivers/power/supply/Makefile +1 -0
@@ -98,3 +98,4 @@ obj-$(CONFIG_CHARGER_BD70528) += bd70528-charger.o obj-$(CONFIG_CHARGER_BD99954) += bd99954-charger.o obj-$(CONFIG_CHARGER_WILCO) += wilco-charger.o obj-$(CONFIG_RN5T618_POWER) += rn5t618_power.o +obj-$(CONFIG_BATTERY_ACER_A500) += acer_a500_battery.o
drivers/power/supply/acer_a500_battery.c new file +297 -0
297 lines not on this page · raw message
Signature · 1 line
2.27.0
PATCH v5 4/4 ARM: tegra: acer-a500: Add Embedded Controller
In reply to Dmitry OsipenkoThis patch adds device-tree node for the Embedded Controller which is found on the Picasso board. The Embedded Controller itself is ENE KB930, it provides functions like battery-gauge/LED/GPIO/etc and it uses firmware that is specifically customized for the Acer A500 device.
--- arch/arm/boot/dts/tegra20-acer-a500-picasso.dts | 17 +++++++++++++++++ 1 file changed, 17 insertions(+)
arch/arm/boot/dts/tegra20-acer-a500-picasso.dts +17 -0
@@ -533,6 +533,16 @@ panel_ddc: i2c@1 { reg = <1>; #address-cells = <1>; #size-cells = <0>; + + embedded-controller@58 { + compatible = "acer,a500-iconia-ec", "ene,kb930"; + reg = <0x58>; + + system-power-controller; + + monitored-battery = <&bat1010>; + power-supplies = <&mains>; + }; }; };
@@ -820,6 +830,13 @@ backlight: backlight { default-brightness-level = <20>; }; + bat1010: battery-2s1p { + compatible = "simple-battery"; + charge-full-design-microamp-hours = <3260000>; + energy-full-design-microwatt-hours = <24000000>; + operating-range-celsius = <0 40>; + }; + /* PMIC has a built-in 32KHz oscillator which is used by PMC */ clk32k_in: clock@0 { compatible = "fixed-clock";
Signature · 1 line
2.27.0