566 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Base driver for Dialog Semiconductor DA9030/DA90344 *5 * Copyright (C) 2008 Compulab, Ltd.6 * Mike Rapoport <mike@compulab.co.il>7 *8 * Copyright (C) 2006-2008 Marvell International Ltd.9 * Eric Miao <eric.miao@marvell.com>10 */11 12#include <linux/kernel.h>13#include <linux/module.h>14#include <linux/interrupt.h>15#include <linux/platform_device.h>16#include <linux/i2c.h>17#include <linux/mfd/da903x.h>18#include <linux/slab.h>19 20#define DA9030_CHIP_ID 0x0021#define DA9030_EVENT_A 0x0122#define DA9030_EVENT_B 0x0223#define DA9030_EVENT_C 0x0324#define DA9030_STATUS 0x0425#define DA9030_IRQ_MASK_A 0x0526#define DA9030_IRQ_MASK_B 0x0627#define DA9030_IRQ_MASK_C 0x0728#define DA9030_SYS_CTRL_A 0x0829#define DA9030_SYS_CTRL_B 0x0930#define DA9030_FAULT_LOG 0x0a31 32#define DA9034_CHIP_ID 0x0033#define DA9034_EVENT_A 0x0134#define DA9034_EVENT_B 0x0235#define DA9034_EVENT_C 0x0336#define DA9034_EVENT_D 0x0437#define DA9034_STATUS_A 0x0538#define DA9034_STATUS_B 0x0639#define DA9034_IRQ_MASK_A 0x0740#define DA9034_IRQ_MASK_B 0x0841#define DA9034_IRQ_MASK_C 0x0942#define DA9034_IRQ_MASK_D 0x0a43#define DA9034_SYS_CTRL_A 0x0b44#define DA9034_SYS_CTRL_B 0x0c45#define DA9034_FAULT_LOG 0x0d46 47struct da903x_chip;48 49struct da903x_chip_ops {50 int (*init_chip)(struct da903x_chip *);51 int (*unmask_events)(struct da903x_chip *, unsigned int events);52 int (*mask_events)(struct da903x_chip *, unsigned int events);53 int (*read_events)(struct da903x_chip *, unsigned int *events);54 int (*read_status)(struct da903x_chip *, unsigned int *status);55};56 57struct da903x_chip {58 struct i2c_client *client;59 struct device *dev;60 const struct da903x_chip_ops *ops;61 62 int type;63 uint32_t events_mask;64 65 struct mutex lock;66 struct work_struct irq_work;67 68 struct blocking_notifier_head notifier_list;69};70 71static inline int __da903x_read(struct i2c_client *client,72 int reg, uint8_t *val)73{74 int ret;75 76 ret = i2c_smbus_read_byte_data(client, reg);77 if (ret < 0) {78 dev_err(&client->dev, "failed reading at 0x%02x\n", reg);79 return ret;80 }81 82 *val = (uint8_t)ret;83 return 0;84}85 86static inline int __da903x_reads(struct i2c_client *client, int reg,87 int len, uint8_t *val)88{89 int ret;90 91 ret = i2c_smbus_read_i2c_block_data(client, reg, len, val);92 if (ret < 0) {93 dev_err(&client->dev, "failed reading from 0x%02x\n", reg);94 return ret;95 }96 return 0;97}98 99static inline int __da903x_write(struct i2c_client *client,100 int reg, uint8_t val)101{102 int ret;103 104 ret = i2c_smbus_write_byte_data(client, reg, val);105 if (ret < 0) {106 dev_err(&client->dev, "failed writing 0x%02x to 0x%02x\n",107 val, reg);108 return ret;109 }110 return 0;111}112 113static inline int __da903x_writes(struct i2c_client *client, int reg,114 int len, uint8_t *val)115{116 int ret;117 118 ret = i2c_smbus_write_i2c_block_data(client, reg, len, val);119 if (ret < 0) {120 dev_err(&client->dev, "failed writings to 0x%02x\n", reg);121 return ret;122 }123 return 0;124}125 126int da903x_register_notifier(struct device *dev, struct notifier_block *nb,127 unsigned int events)128{129 struct da903x_chip *chip = dev_get_drvdata(dev);130 131 chip->ops->unmask_events(chip, events);132 return blocking_notifier_chain_register(&chip->notifier_list, nb);133}134EXPORT_SYMBOL_GPL(da903x_register_notifier);135 136int da903x_unregister_notifier(struct device *dev, struct notifier_block *nb,137 unsigned int events)138{139 struct da903x_chip *chip = dev_get_drvdata(dev);140 141 chip->ops->mask_events(chip, events);142 return blocking_notifier_chain_unregister(&chip->notifier_list, nb);143}144EXPORT_SYMBOL_GPL(da903x_unregister_notifier);145 146int da903x_write(struct device *dev, int reg, uint8_t val)147{148 return __da903x_write(to_i2c_client(dev), reg, val);149}150EXPORT_SYMBOL_GPL(da903x_write);151 152int da903x_writes(struct device *dev, int reg, int len, uint8_t *val)153{154 return __da903x_writes(to_i2c_client(dev), reg, len, val);155}156EXPORT_SYMBOL_GPL(da903x_writes);157 158int da903x_read(struct device *dev, int reg, uint8_t *val)159{160 return __da903x_read(to_i2c_client(dev), reg, val);161}162EXPORT_SYMBOL_GPL(da903x_read);163 164int da903x_reads(struct device *dev, int reg, int len, uint8_t *val)165{166 return __da903x_reads(to_i2c_client(dev), reg, len, val);167}168EXPORT_SYMBOL_GPL(da903x_reads);169 170int da903x_set_bits(struct device *dev, int reg, uint8_t bit_mask)171{172 struct da903x_chip *chip = dev_get_drvdata(dev);173 uint8_t reg_val;174 int ret = 0;175 176 mutex_lock(&chip->lock);177 178 ret = __da903x_read(chip->client, reg, ®_val);179 if (ret)180 goto out;181 182 if ((reg_val & bit_mask) != bit_mask) {183 reg_val |= bit_mask;184 ret = __da903x_write(chip->client, reg, reg_val);185 }186out:187 mutex_unlock(&chip->lock);188 return ret;189}190EXPORT_SYMBOL_GPL(da903x_set_bits);191 192int da903x_clr_bits(struct device *dev, int reg, uint8_t bit_mask)193{194 struct da903x_chip *chip = dev_get_drvdata(dev);195 uint8_t reg_val;196 int ret = 0;197 198 mutex_lock(&chip->lock);199 200 ret = __da903x_read(chip->client, reg, ®_val);201 if (ret)202 goto out;203 204 if (reg_val & bit_mask) {205 reg_val &= ~bit_mask;206 ret = __da903x_write(chip->client, reg, reg_val);207 }208out:209 mutex_unlock(&chip->lock);210 return ret;211}212EXPORT_SYMBOL_GPL(da903x_clr_bits);213 214int da903x_update(struct device *dev, int reg, uint8_t val, uint8_t mask)215{216 struct da903x_chip *chip = dev_get_drvdata(dev);217 uint8_t reg_val;218 int ret = 0;219 220 mutex_lock(&chip->lock);221 222 ret = __da903x_read(chip->client, reg, ®_val);223 if (ret)224 goto out;225 226 if ((reg_val & mask) != val) {227 reg_val = (reg_val & ~mask) | val;228 ret = __da903x_write(chip->client, reg, reg_val);229 }230out:231 mutex_unlock(&chip->lock);232 return ret;233}234EXPORT_SYMBOL_GPL(da903x_update);235 236int da903x_query_status(struct device *dev, unsigned int sbits)237{238 struct da903x_chip *chip = dev_get_drvdata(dev);239 unsigned int status = 0;240 241 chip->ops->read_status(chip, &status);242 return ((status & sbits) == sbits);243}244EXPORT_SYMBOL(da903x_query_status);245 246static int da9030_init_chip(struct da903x_chip *chip)247{248 uint8_t chip_id;249 int err;250 251 err = __da903x_read(chip->client, DA9030_CHIP_ID, &chip_id);252 if (err)253 return err;254 255 err = __da903x_write(chip->client, DA9030_SYS_CTRL_A, 0xE8);256 if (err)257 return err;258 259 dev_info(chip->dev, "DA9030 (CHIP ID: 0x%02x) detected\n", chip_id);260 return 0;261}262 263static int da9030_unmask_events(struct da903x_chip *chip, unsigned int events)264{265 uint8_t v[3];266 267 chip->events_mask &= ~events;268 269 v[0] = (chip->events_mask & 0xff);270 v[1] = (chip->events_mask >> 8) & 0xff;271 v[2] = (chip->events_mask >> 16) & 0xff;272 273 return __da903x_writes(chip->client, DA9030_IRQ_MASK_A, 3, v);274}275 276static int da9030_mask_events(struct da903x_chip *chip, unsigned int events)277{278 uint8_t v[3];279 280 chip->events_mask |= events;281 282 v[0] = (chip->events_mask & 0xff);283 v[1] = (chip->events_mask >> 8) & 0xff;284 v[2] = (chip->events_mask >> 16) & 0xff;285 286 return __da903x_writes(chip->client, DA9030_IRQ_MASK_A, 3, v);287}288 289static int da9030_read_events(struct da903x_chip *chip, unsigned int *events)290{291 uint8_t v[3] = {0, 0, 0};292 int ret;293 294 ret = __da903x_reads(chip->client, DA9030_EVENT_A, 3, v);295 if (ret < 0)296 return ret;297 298 *events = (v[2] << 16) | (v[1] << 8) | v[0];299 return 0;300}301 302static int da9030_read_status(struct da903x_chip *chip, unsigned int *status)303{304 return __da903x_read(chip->client, DA9030_STATUS, (uint8_t *)status);305}306 307static int da9034_init_chip(struct da903x_chip *chip)308{309 uint8_t chip_id;310 int err;311 312 err = __da903x_read(chip->client, DA9034_CHIP_ID, &chip_id);313 if (err)314 return err;315 316 err = __da903x_write(chip->client, DA9034_SYS_CTRL_A, 0xE8);317 if (err)318 return err;319 320 /* avoid SRAM power off during sleep*/321 __da903x_write(chip->client, 0x10, 0x07);322 __da903x_write(chip->client, 0x11, 0xff);323 __da903x_write(chip->client, 0x12, 0xff);324 325 /* Enable the ONKEY power down functionality */326 __da903x_write(chip->client, DA9034_SYS_CTRL_B, 0x20);327 __da903x_write(chip->client, DA9034_SYS_CTRL_A, 0x60);328 329 /* workaround to make LEDs work */330 __da903x_write(chip->client, 0x90, 0x01);331 __da903x_write(chip->client, 0xB0, 0x08);332 333 /* make ADTV1 and SDTV1 effective */334 __da903x_write(chip->client, 0x20, 0x00);335 336 dev_info(chip->dev, "DA9034 (CHIP ID: 0x%02x) detected\n", chip_id);337 return 0;338}339 340static int da9034_unmask_events(struct da903x_chip *chip, unsigned int events)341{342 uint8_t v[4];343 344 chip->events_mask &= ~events;345 346 v[0] = (chip->events_mask & 0xff);347 v[1] = (chip->events_mask >> 8) & 0xff;348 v[2] = (chip->events_mask >> 16) & 0xff;349 v[3] = (chip->events_mask >> 24) & 0xff;350 351 return __da903x_writes(chip->client, DA9034_IRQ_MASK_A, 4, v);352}353 354static int da9034_mask_events(struct da903x_chip *chip, unsigned int events)355{356 uint8_t v[4];357 358 chip->events_mask |= events;359 360 v[0] = (chip->events_mask & 0xff);361 v[1] = (chip->events_mask >> 8) & 0xff;362 v[2] = (chip->events_mask >> 16) & 0xff;363 v[3] = (chip->events_mask >> 24) & 0xff;364 365 return __da903x_writes(chip->client, DA9034_IRQ_MASK_A, 4, v);366}367 368static int da9034_read_events(struct da903x_chip *chip, unsigned int *events)369{370 uint8_t v[4] = {0, 0, 0, 0};371 int ret;372 373 ret = __da903x_reads(chip->client, DA9034_EVENT_A, 4, v);374 if (ret < 0)375 return ret;376 377 *events = (v[3] << 24) | (v[2] << 16) | (v[1] << 8) | v[0];378 return 0;379}380 381static int da9034_read_status(struct da903x_chip *chip, unsigned int *status)382{383 uint8_t v[2] = {0, 0};384 int ret = 0;385 386 ret = __da903x_reads(chip->client, DA9034_STATUS_A, 2, v);387 if (ret)388 return ret;389 390 *status = (v[1] << 8) | v[0];391 return 0;392}393 394static void da903x_irq_work(struct work_struct *work)395{396 struct da903x_chip *chip =397 container_of(work, struct da903x_chip, irq_work);398 unsigned int events = 0;399 400 while (1) {401 if (chip->ops->read_events(chip, &events))402 break;403 404 events &= ~chip->events_mask;405 if (events == 0)406 break;407 408 blocking_notifier_call_chain(409 &chip->notifier_list, events, NULL);410 }411 enable_irq(chip->client->irq);412}413 414static irqreturn_t da903x_irq_handler(int irq, void *data)415{416 struct da903x_chip *chip = data;417 418 disable_irq_nosync(irq);419 (void)schedule_work(&chip->irq_work);420 421 return IRQ_HANDLED;422}423 424static const struct da903x_chip_ops da903x_ops[] = {425 [0] = {426 .init_chip = da9030_init_chip,427 .unmask_events = da9030_unmask_events,428 .mask_events = da9030_mask_events,429 .read_events = da9030_read_events,430 .read_status = da9030_read_status,431 },432 [1] = {433 .init_chip = da9034_init_chip,434 .unmask_events = da9034_unmask_events,435 .mask_events = da9034_mask_events,436 .read_events = da9034_read_events,437 .read_status = da9034_read_status,438 }439};440 441static const struct i2c_device_id da903x_id_table[] = {442 { "da9030", 0 },443 { "da9034", 1 },444 { },445};446MODULE_DEVICE_TABLE(i2c, da903x_id_table);447 448static int __remove_subdev(struct device *dev, void *unused)449{450 platform_device_unregister(to_platform_device(dev));451 return 0;452}453 454static int da903x_remove_subdevs(struct da903x_chip *chip)455{456 return device_for_each_child(chip->dev, NULL, __remove_subdev);457}458 459static int da903x_add_subdevs(struct da903x_chip *chip,460 struct da903x_platform_data *pdata)461{462 struct da903x_subdev_info *subdev;463 struct platform_device *pdev;464 int i, ret = 0;465 466 for (i = 0; i < pdata->num_subdevs; i++) {467 subdev = &pdata->subdevs[i];468 469 pdev = platform_device_alloc(subdev->name, subdev->id);470 if (!pdev) {471 ret = -ENOMEM;472 goto failed;473 }474 475 pdev->dev.parent = chip->dev;476 pdev->dev.platform_data = subdev->platform_data;477 478 ret = platform_device_add(pdev);479 if (ret) {480 platform_device_put(pdev);481 goto failed;482 }483 }484 return 0;485 486failed:487 da903x_remove_subdevs(chip);488 return ret;489}490 491static int da903x_probe(struct i2c_client *client)492{493 const struct i2c_device_id *id = i2c_client_get_device_id(client);494 struct da903x_platform_data *pdata = dev_get_platdata(&client->dev);495 struct da903x_chip *chip;496 unsigned int tmp;497 int ret;498 499 chip = devm_kzalloc(&client->dev, sizeof(struct da903x_chip),500 GFP_KERNEL);501 if (chip == NULL)502 return -ENOMEM;503 504 chip->client = client;505 chip->dev = &client->dev;506 chip->ops = &da903x_ops[id->driver_data];507 508 mutex_init(&chip->lock);509 INIT_WORK(&chip->irq_work, da903x_irq_work);510 BLOCKING_INIT_NOTIFIER_HEAD(&chip->notifier_list);511 512 i2c_set_clientdata(client, chip);513 514 ret = chip->ops->init_chip(chip);515 if (ret)516 return ret;517 518 /* mask and clear all IRQs */519 chip->events_mask = 0xffffffff;520 chip->ops->mask_events(chip, chip->events_mask);521 chip->ops->read_events(chip, &tmp);522 523 ret = devm_request_irq(&client->dev, client->irq, da903x_irq_handler,524 IRQF_TRIGGER_FALLING,525 "da903x", chip);526 if (ret) {527 dev_err(&client->dev, "failed to request irq %d\n",528 client->irq);529 return ret;530 }531 532 return da903x_add_subdevs(chip, pdata);533}534 535static void da903x_remove(struct i2c_client *client)536{537 struct da903x_chip *chip = i2c_get_clientdata(client);538 539 da903x_remove_subdevs(chip);540}541 542static struct i2c_driver da903x_driver = {543 .driver = {544 .name = "da903x",545 },546 .probe = da903x_probe,547 .remove = da903x_remove,548 .id_table = da903x_id_table,549};550 551static int __init da903x_init(void)552{553 return i2c_add_driver(&da903x_driver);554}555subsys_initcall(da903x_init);556 557static void __exit da903x_exit(void)558{559 i2c_del_driver(&da903x_driver);560}561module_exit(da903x_exit);562 563MODULE_DESCRIPTION("PMIC Driver for Dialog Semiconductor DA9034");564MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>");565MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");566