0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/acpi.h>
0011 #include <linux/completion.h>
0012 #include <linux/delay.h>
0013 #include <linux/i2c.h>
0014 #include <linux/interrupt.h>
0015 #include <linux/irq.h>
0016 #include <linux/irqdomain.h>
0017 #include <linux/mfd/intel_soc_pmic.h>
0018 #include <linux/module.h>
0019 #include <linux/platform_device.h>
0020 #include <linux/power/bq24190_charger.h>
0021 #include <linux/power/bq25890_charger.h>
0022 #include <linux/slab.h>
0023
0024 #define CHT_WC_I2C_CTRL 0x5e24
0025 #define CHT_WC_I2C_CTRL_WR BIT(0)
0026 #define CHT_WC_I2C_CTRL_RD BIT(1)
0027 #define CHT_WC_I2C_CLIENT_ADDR 0x5e25
0028 #define CHT_WC_I2C_REG_OFFSET 0x5e26
0029 #define CHT_WC_I2C_WRDATA 0x5e27
0030 #define CHT_WC_I2C_RDDATA 0x5e28
0031
0032 #define CHT_WC_EXTCHGRIRQ 0x6e0a
0033 #define CHT_WC_EXTCHGRIRQ_CLIENT_IRQ BIT(0)
0034 #define CHT_WC_EXTCHGRIRQ_WRITE_IRQ BIT(1)
0035 #define CHT_WC_EXTCHGRIRQ_READ_IRQ BIT(2)
0036 #define CHT_WC_EXTCHGRIRQ_NACK_IRQ BIT(3)
0037 #define CHT_WC_EXTCHGRIRQ_ADAP_IRQMASK ((u8)GENMASK(3, 1))
0038 #define CHT_WC_EXTCHGRIRQ_MSK 0x6e17
0039
0040 struct cht_wc_i2c_adap {
0041 struct i2c_adapter adapter;
0042 wait_queue_head_t wait;
0043 struct irq_chip irqchip;
0044 struct mutex adap_lock;
0045 struct mutex irqchip_lock;
0046 struct regmap *regmap;
0047 struct irq_domain *irq_domain;
0048 struct i2c_client *client;
0049 int client_irq;
0050 u8 irq_mask;
0051 u8 old_irq_mask;
0052 int read_data;
0053 bool io_error;
0054 bool done;
0055 };
0056
0057 static irqreturn_t cht_wc_i2c_adap_thread_handler(int id, void *data)
0058 {
0059 struct cht_wc_i2c_adap *adap = data;
0060 int ret, reg;
0061
0062 mutex_lock(&adap->adap_lock);
0063
0064
0065 ret = regmap_read(adap->regmap, CHT_WC_EXTCHGRIRQ, ®);
0066 if (ret) {
0067 dev_err(&adap->adapter.dev, "Error reading extchgrirq reg\n");
0068 mutex_unlock(&adap->adap_lock);
0069 return IRQ_NONE;
0070 }
0071
0072 reg &= ~adap->irq_mask;
0073
0074
0075 ret = regmap_read(adap->regmap, CHT_WC_I2C_RDDATA, &adap->read_data);
0076 if (ret)
0077 adap->io_error = true;
0078
0079
0080
0081
0082
0083 ret = regmap_write(adap->regmap, CHT_WC_EXTCHGRIRQ, reg);
0084 if (ret)
0085 dev_err(&adap->adapter.dev, "Error writing extchgrirq reg\n");
0086
0087 if (reg & CHT_WC_EXTCHGRIRQ_ADAP_IRQMASK) {
0088 adap->io_error |= !!(reg & CHT_WC_EXTCHGRIRQ_NACK_IRQ);
0089 adap->done = true;
0090 }
0091
0092 mutex_unlock(&adap->adap_lock);
0093
0094 if (reg & CHT_WC_EXTCHGRIRQ_ADAP_IRQMASK)
0095 wake_up(&adap->wait);
0096
0097
0098
0099
0100
0101
0102
0103 if (reg & CHT_WC_EXTCHGRIRQ_CLIENT_IRQ)
0104 generic_handle_irq_safe(adap->client_irq);
0105
0106 return IRQ_HANDLED;
0107 }
0108
0109 static u32 cht_wc_i2c_adap_master_func(struct i2c_adapter *adap)
0110 {
0111
0112 return I2C_FUNC_SMBUS_BYTE_DATA;
0113 }
0114
0115 static int cht_wc_i2c_adap_smbus_xfer(struct i2c_adapter *_adap, u16 addr,
0116 unsigned short flags, char read_write,
0117 u8 command, int size,
0118 union i2c_smbus_data *data)
0119 {
0120 struct cht_wc_i2c_adap *adap = i2c_get_adapdata(_adap);
0121 int ret;
0122
0123 mutex_lock(&adap->adap_lock);
0124 adap->io_error = false;
0125 adap->done = false;
0126 mutex_unlock(&adap->adap_lock);
0127
0128 ret = regmap_write(adap->regmap, CHT_WC_I2C_CLIENT_ADDR, addr);
0129 if (ret)
0130 return ret;
0131
0132 if (read_write == I2C_SMBUS_WRITE) {
0133 ret = regmap_write(adap->regmap, CHT_WC_I2C_WRDATA, data->byte);
0134 if (ret)
0135 return ret;
0136 }
0137
0138 ret = regmap_write(adap->regmap, CHT_WC_I2C_REG_OFFSET, command);
0139 if (ret)
0140 return ret;
0141
0142 ret = regmap_write(adap->regmap, CHT_WC_I2C_CTRL,
0143 (read_write == I2C_SMBUS_WRITE) ?
0144 CHT_WC_I2C_CTRL_WR : CHT_WC_I2C_CTRL_RD);
0145 if (ret)
0146 return ret;
0147
0148 ret = wait_event_timeout(adap->wait, adap->done, msecs_to_jiffies(30));
0149 if (ret == 0) {
0150
0151
0152
0153
0154 cht_wc_i2c_adap_thread_handler(0, adap);
0155 if (!adap->done)
0156 return -ETIMEDOUT;
0157 }
0158
0159 ret = 0;
0160 mutex_lock(&adap->adap_lock);
0161 if (adap->io_error)
0162 ret = -EIO;
0163 else if (read_write == I2C_SMBUS_READ)
0164 data->byte = adap->read_data;
0165 mutex_unlock(&adap->adap_lock);
0166
0167 return ret;
0168 }
0169
0170 static const struct i2c_algorithm cht_wc_i2c_adap_algo = {
0171 .functionality = cht_wc_i2c_adap_master_func,
0172 .smbus_xfer = cht_wc_i2c_adap_smbus_xfer,
0173 };
0174
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196 static void cht_wc_i2c_adap_lock_bus(struct i2c_adapter *adapter,
0197 unsigned int flags)
0198 {
0199 rt_mutex_lock_nested(&adapter->bus_lock, 1);
0200 }
0201
0202 static int cht_wc_i2c_adap_trylock_bus(struct i2c_adapter *adapter,
0203 unsigned int flags)
0204 {
0205 return rt_mutex_trylock(&adapter->bus_lock);
0206 }
0207
0208 static void cht_wc_i2c_adap_unlock_bus(struct i2c_adapter *adapter,
0209 unsigned int flags)
0210 {
0211 rt_mutex_unlock(&adapter->bus_lock);
0212 }
0213
0214 static const struct i2c_lock_operations cht_wc_i2c_adap_lock_ops = {
0215 .lock_bus = cht_wc_i2c_adap_lock_bus,
0216 .trylock_bus = cht_wc_i2c_adap_trylock_bus,
0217 .unlock_bus = cht_wc_i2c_adap_unlock_bus,
0218 };
0219
0220
0221 static void cht_wc_i2c_irq_lock(struct irq_data *data)
0222 {
0223 struct cht_wc_i2c_adap *adap = irq_data_get_irq_chip_data(data);
0224
0225 mutex_lock(&adap->irqchip_lock);
0226 }
0227
0228 static void cht_wc_i2c_irq_sync_unlock(struct irq_data *data)
0229 {
0230 struct cht_wc_i2c_adap *adap = irq_data_get_irq_chip_data(data);
0231 int ret;
0232
0233 if (adap->irq_mask != adap->old_irq_mask) {
0234 ret = regmap_write(adap->regmap, CHT_WC_EXTCHGRIRQ_MSK,
0235 adap->irq_mask);
0236 if (ret == 0)
0237 adap->old_irq_mask = adap->irq_mask;
0238 else
0239 dev_err(&adap->adapter.dev, "Error writing EXTCHGRIRQ_MSK\n");
0240 }
0241
0242 mutex_unlock(&adap->irqchip_lock);
0243 }
0244
0245 static void cht_wc_i2c_irq_enable(struct irq_data *data)
0246 {
0247 struct cht_wc_i2c_adap *adap = irq_data_get_irq_chip_data(data);
0248
0249 adap->irq_mask &= ~CHT_WC_EXTCHGRIRQ_CLIENT_IRQ;
0250 }
0251
0252 static void cht_wc_i2c_irq_disable(struct irq_data *data)
0253 {
0254 struct cht_wc_i2c_adap *adap = irq_data_get_irq_chip_data(data);
0255
0256 adap->irq_mask |= CHT_WC_EXTCHGRIRQ_CLIENT_IRQ;
0257 }
0258
0259 static const struct irq_chip cht_wc_i2c_irq_chip = {
0260 .irq_bus_lock = cht_wc_i2c_irq_lock,
0261 .irq_bus_sync_unlock = cht_wc_i2c_irq_sync_unlock,
0262 .irq_disable = cht_wc_i2c_irq_disable,
0263 .irq_enable = cht_wc_i2c_irq_enable,
0264 .name = "cht_wc_ext_chrg_irq_chip",
0265 };
0266
0267
0268 static const char * const bq24190_suppliers[] = {
0269 "tcpm-source-psy-i2c-fusb302" };
0270
0271 static const struct property_entry bq24190_props[] = {
0272 PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq24190_suppliers),
0273 PROPERTY_ENTRY_BOOL("omit-battery-class"),
0274 PROPERTY_ENTRY_BOOL("disable-reset"),
0275 { }
0276 };
0277
0278 static const struct software_node bq24190_node = {
0279 .properties = bq24190_props,
0280 };
0281
0282 static struct regulator_consumer_supply fusb302_consumer = {
0283 .supply = "vbus",
0284
0285 .dev_name = "i2c-fusb302",
0286 };
0287
0288 static const struct regulator_init_data bq24190_vbus_init_data = {
0289 .constraints = {
0290
0291 .name = "cht_wc_usb_typec_vbus",
0292 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
0293 },
0294 .consumer_supplies = &fusb302_consumer,
0295 .num_consumer_supplies = 1,
0296 };
0297
0298 static struct bq24190_platform_data bq24190_pdata = {
0299 .regulator_init_data = &bq24190_vbus_init_data,
0300 };
0301
0302 static struct i2c_board_info gpd_win_board_info = {
0303 .type = "bq24190",
0304 .addr = 0x6b,
0305 .dev_name = "bq24190",
0306 .swnode = &bq24190_node,
0307 .platform_data = &bq24190_pdata,
0308 };
0309
0310
0311 static struct regulator_consumer_supply bq2589x_vbus_consumer = {
0312 .supply = "vbus",
0313 .dev_name = "cht_wcove_pwrsrc",
0314 };
0315
0316 static const struct regulator_init_data bq2589x_vbus_init_data = {
0317 .constraints = {
0318 .valid_ops_mask = REGULATOR_CHANGE_STATUS,
0319 },
0320 .consumer_supplies = &bq2589x_vbus_consumer,
0321 .num_consumer_supplies = 1,
0322 };
0323
0324 static struct bq25890_platform_data bq2589x_pdata = {
0325 .regulator_init_data = &bq2589x_vbus_init_data,
0326 };
0327
0328 static const struct property_entry xiaomi_mipad2_props[] = {
0329 PROPERTY_ENTRY_BOOL("linux,skip-reset"),
0330 PROPERTY_ENTRY_BOOL("linux,read-back-settings"),
0331 { }
0332 };
0333
0334 static const struct software_node xiaomi_mipad2_node = {
0335 .properties = xiaomi_mipad2_props,
0336 };
0337
0338 static struct i2c_board_info xiaomi_mipad2_board_info = {
0339 .type = "bq25890",
0340 .addr = 0x6a,
0341 .dev_name = "bq25890",
0342 .swnode = &xiaomi_mipad2_node,
0343 .platform_data = &bq2589x_pdata,
0344 };
0345
0346
0347 static const char * const lenovo_yb1_bq25892_suppliers[] = { "cht_wcove_pwrsrc" };
0348
0349 static const struct property_entry lenovo_yb1_bq25892_props[] = {
0350 PROPERTY_ENTRY_STRING_ARRAY("supplied-from",
0351 lenovo_yb1_bq25892_suppliers),
0352 PROPERTY_ENTRY_U32("linux,pump-express-vbus-max", 12000000),
0353 PROPERTY_ENTRY_BOOL("linux,skip-reset"),
0354
0355
0356
0357
0358
0359
0360 PROPERTY_ENTRY_U32("ti,charge-current", 4224000),
0361 PROPERTY_ENTRY_U32("ti,battery-regulation-voltage", 4352000),
0362 PROPERTY_ENTRY_U32("ti,termination-current", 256000),
0363 PROPERTY_ENTRY_U32("ti,precharge-current", 128000),
0364 PROPERTY_ENTRY_U32("ti,minimum-sys-voltage", 3500000),
0365 PROPERTY_ENTRY_U32("ti,boost-voltage", 4998000),
0366 PROPERTY_ENTRY_U32("ti,boost-max-current", 1400000),
0367 PROPERTY_ENTRY_BOOL("ti,use-ilim-pin"),
0368 { }
0369 };
0370
0371 static const struct software_node lenovo_yb1_bq25892_node = {
0372 .properties = lenovo_yb1_bq25892_props,
0373 };
0374
0375 static struct i2c_board_info lenovo_yogabook1_board_info = {
0376 .type = "bq25892",
0377 .addr = 0x6b,
0378 .dev_name = "bq25892",
0379 .swnode = &lenovo_yb1_bq25892_node,
0380 .platform_data = &bq2589x_pdata,
0381 };
0382
0383 static int cht_wc_i2c_adap_i2c_probe(struct platform_device *pdev)
0384 {
0385 struct intel_soc_pmic *pmic = dev_get_drvdata(pdev->dev.parent);
0386 struct i2c_board_info *board_info = NULL;
0387 struct cht_wc_i2c_adap *adap;
0388 int ret, reg, irq;
0389
0390 irq = platform_get_irq(pdev, 0);
0391 if (irq < 0)
0392 return irq;
0393
0394 adap = devm_kzalloc(&pdev->dev, sizeof(*adap), GFP_KERNEL);
0395 if (!adap)
0396 return -ENOMEM;
0397
0398 init_waitqueue_head(&adap->wait);
0399 mutex_init(&adap->adap_lock);
0400 mutex_init(&adap->irqchip_lock);
0401 adap->irqchip = cht_wc_i2c_irq_chip;
0402 adap->regmap = pmic->regmap;
0403 adap->adapter.owner = THIS_MODULE;
0404 adap->adapter.class = I2C_CLASS_HWMON;
0405 adap->adapter.algo = &cht_wc_i2c_adap_algo;
0406 adap->adapter.lock_ops = &cht_wc_i2c_adap_lock_ops;
0407 strscpy(adap->adapter.name, "PMIC I2C Adapter",
0408 sizeof(adap->adapter.name));
0409 adap->adapter.dev.parent = &pdev->dev;
0410
0411
0412 adap->old_irq_mask = adap->irq_mask = ~CHT_WC_EXTCHGRIRQ_ADAP_IRQMASK;
0413
0414 ret = regmap_read(adap->regmap, CHT_WC_I2C_RDDATA, ®);
0415 if (ret)
0416 return ret;
0417
0418 ret = regmap_write(adap->regmap, CHT_WC_EXTCHGRIRQ, ~adap->irq_mask);
0419 if (ret)
0420 return ret;
0421
0422 ret = regmap_write(adap->regmap, CHT_WC_EXTCHGRIRQ_MSK, adap->irq_mask);
0423 if (ret)
0424 return ret;
0425
0426
0427 adap->irq_domain = irq_domain_add_linear(NULL, 1, &irq_domain_simple_ops, NULL);
0428 if (!adap->irq_domain)
0429 return -ENOMEM;
0430
0431 adap->client_irq = irq_create_mapping(adap->irq_domain, 0);
0432 if (!adap->client_irq) {
0433 ret = -ENOMEM;
0434 goto remove_irq_domain;
0435 }
0436
0437 irq_set_chip_data(adap->client_irq, adap);
0438 irq_set_chip_and_handler(adap->client_irq, &adap->irqchip,
0439 handle_simple_irq);
0440
0441 ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
0442 cht_wc_i2c_adap_thread_handler,
0443 IRQF_ONESHOT, "PMIC I2C Adapter", adap);
0444 if (ret)
0445 goto remove_irq_domain;
0446
0447 i2c_set_adapdata(&adap->adapter, adap);
0448 ret = i2c_add_adapter(&adap->adapter);
0449 if (ret)
0450 goto remove_irq_domain;
0451
0452 switch (pmic->cht_wc_model) {
0453 case INTEL_CHT_WC_GPD_WIN_POCKET:
0454 board_info = &gpd_win_board_info;
0455 break;
0456 case INTEL_CHT_WC_XIAOMI_MIPAD2:
0457 board_info = &xiaomi_mipad2_board_info;
0458 break;
0459 case INTEL_CHT_WC_LENOVO_YOGABOOK1:
0460 board_info = &lenovo_yogabook1_board_info;
0461 break;
0462 default:
0463 dev_warn(&pdev->dev, "Unknown model, not instantiating charger device\n");
0464 break;
0465 }
0466
0467 if (board_info) {
0468 board_info->irq = adap->client_irq;
0469 adap->client = i2c_new_client_device(&adap->adapter, board_info);
0470 if (IS_ERR(adap->client)) {
0471 ret = PTR_ERR(adap->client);
0472 goto del_adapter;
0473 }
0474 }
0475
0476 platform_set_drvdata(pdev, adap);
0477 return 0;
0478
0479 del_adapter:
0480 i2c_del_adapter(&adap->adapter);
0481 remove_irq_domain:
0482 irq_domain_remove(adap->irq_domain);
0483 return ret;
0484 }
0485
0486 static int cht_wc_i2c_adap_i2c_remove(struct platform_device *pdev)
0487 {
0488 struct cht_wc_i2c_adap *adap = platform_get_drvdata(pdev);
0489
0490 i2c_unregister_device(adap->client);
0491 i2c_del_adapter(&adap->adapter);
0492 irq_domain_remove(adap->irq_domain);
0493
0494 return 0;
0495 }
0496
0497 static const struct platform_device_id cht_wc_i2c_adap_id_table[] = {
0498 { .name = "cht_wcove_ext_chgr" },
0499 {},
0500 };
0501 MODULE_DEVICE_TABLE(platform, cht_wc_i2c_adap_id_table);
0502
0503 static struct platform_driver cht_wc_i2c_adap_driver = {
0504 .probe = cht_wc_i2c_adap_i2c_probe,
0505 .remove = cht_wc_i2c_adap_i2c_remove,
0506 .driver = {
0507 .name = "cht_wcove_ext_chgr",
0508 },
0509 .id_table = cht_wc_i2c_adap_id_table,
0510 };
0511 module_platform_driver(cht_wc_i2c_adap_driver);
0512
0513 MODULE_DESCRIPTION("Intel CHT Whiskey Cove PMIC I2C Master driver");
0514 MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
0515 MODULE_LICENSE("GPL");