Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mfd: ntxec: Support for EC in Tolino Shine 2 HD

Add the version of the EC in the Tolino Shine 2 HD
to the supported versions. It seems not to have an RTC
and does not ack data written to it.
The vendor kernel happily ignores write errors, using
I2C via userspace i2c-set also shows the error.
So add a quirk to ignore that error.

PWM can be successfully configured despite of that error.

Signed-off-by: Andreas Kemnade <andreas@kemnade.info>
Reviewed-by: Jonathan Neuschäfer <j.neuschaefer@gmx.net>
Signed-off-by: Lee Jones <lee.jones@linaro.org>

authored by

Andreas Kemnade and committed by
Lee Jones
d1157530 4917e498

+54 -3
+53 -3
drivers/mfd/ntxec.c
··· 96 96 .priority = 128, 97 97 }; 98 98 99 + static int regmap_ignore_write(void *context, 100 + unsigned int reg, unsigned int val) 101 + 102 + { 103 + struct regmap *regmap = context; 104 + 105 + regmap_write(regmap, reg, val); 106 + 107 + return 0; 108 + } 109 + 110 + static int regmap_wrap_read(void *context, unsigned int reg, 111 + unsigned int *val) 112 + { 113 + struct regmap *regmap = context; 114 + 115 + return regmap_read(regmap, reg, val); 116 + } 117 + 118 + /* 119 + * Some firmware versions do not ack written data, add a wrapper. It 120 + * is used to stack another regmap on top. 121 + */ 122 + static const struct regmap_config regmap_config_noack = { 123 + .name = "ntxec_noack", 124 + .reg_bits = 8, 125 + .val_bits = 16, 126 + .cache_type = REGCACHE_NONE, 127 + .reg_write = regmap_ignore_write, 128 + .reg_read = regmap_wrap_read 129 + }; 130 + 99 131 static const struct regmap_config regmap_config = { 100 132 .name = "ntxec", 101 133 .reg_bits = 8, ··· 136 104 .val_format_endian = REGMAP_ENDIAN_BIG, 137 105 }; 138 106 139 - static const struct mfd_cell ntxec_subdevices[] = { 107 + static const struct mfd_cell ntxec_subdev[] = { 140 108 { .name = "ntxec-rtc" }, 109 + { .name = "ntxec-pwm" }, 110 + }; 111 + 112 + static const struct mfd_cell ntxec_subdev_pwm[] = { 141 113 { .name = "ntxec-pwm" }, 142 114 }; 143 115 ··· 150 114 struct ntxec *ec; 151 115 unsigned int version; 152 116 int res; 117 + const struct mfd_cell *subdevs; 118 + size_t n_subdevs; 153 119 154 120 ec = devm_kmalloc(&client->dev, sizeof(*ec), GFP_KERNEL); 155 121 if (!ec) ··· 175 137 /* Bail out if we encounter an unknown firmware version */ 176 138 switch (version) { 177 139 case NTXEC_VERSION_KOBO_AURA: 140 + subdevs = ntxec_subdev; 141 + n_subdevs = ARRAY_SIZE(ntxec_subdev); 142 + break; 143 + case NTXEC_VERSION_TOLINO_SHINE2: 144 + subdevs = ntxec_subdev_pwm; 145 + n_subdevs = ARRAY_SIZE(ntxec_subdev_pwm); 146 + /* Another regmap stacked on top of the other */ 147 + ec->regmap = devm_regmap_init(ec->dev, NULL, 148 + ec->regmap, 149 + &regmap_config_noack); 150 + if (IS_ERR(ec->regmap)) 151 + return PTR_ERR(ec->regmap); 178 152 break; 179 153 default: 180 154 dev_err(ec->dev, ··· 231 181 232 182 i2c_set_clientdata(client, ec); 233 183 234 - res = devm_mfd_add_devices(ec->dev, PLATFORM_DEVID_NONE, ntxec_subdevices, 235 - ARRAY_SIZE(ntxec_subdevices), NULL, 0, NULL); 184 + res = devm_mfd_add_devices(ec->dev, PLATFORM_DEVID_NONE, 185 + subdevs, n_subdevs, NULL, 0, NULL); 236 186 if (res) 237 187 dev_err(ec->dev, "Failed to add subdevices: %d\n", res); 238 188
+1
include/linux/mfd/ntxec.h
··· 33 33 34 34 /* Known firmware versions */ 35 35 #define NTXEC_VERSION_KOBO_AURA 0xd726 /* found in Kobo Aura */ 36 + #define NTXEC_VERSION_TOLINO_SHINE2 0xf110 /* found in Tolino Shine 2 HD */ 36 37 37 38 #endif