Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0-only 2 : : /* 3 : : * ST Microelectronics MFD: stmpe's i2c client specific driver 4 : : * 5 : : * Copyright (C) ST-Ericsson SA 2010 6 : : * Copyright (C) ST Microelectronics SA 2011 7 : : * 8 : : * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson 9 : : * Author: Viresh Kumar <vireshk@kernel.org> for ST Microelectronics 10 : : */ 11 : : 12 : : #include <linux/i2c.h> 13 : : #include <linux/interrupt.h> 14 : : #include <linux/kernel.h> 15 : : #include <linux/module.h> 16 : : #include <linux/types.h> 17 : : #include <linux/of_device.h> 18 : : #include "stmpe.h" 19 : : 20 : 0 : static int i2c_reg_read(struct stmpe *stmpe, u8 reg) 21 : : { 22 : 0 : struct i2c_client *i2c = stmpe->client; 23 : : 24 : 0 : return i2c_smbus_read_byte_data(i2c, reg); 25 : : } 26 : : 27 : 0 : static int i2c_reg_write(struct stmpe *stmpe, u8 reg, u8 val) 28 : : { 29 : 0 : struct i2c_client *i2c = stmpe->client; 30 : : 31 : 0 : return i2c_smbus_write_byte_data(i2c, reg, val); 32 : : } 33 : : 34 : 0 : static int i2c_block_read(struct stmpe *stmpe, u8 reg, u8 length, u8 *values) 35 : : { 36 : 0 : struct i2c_client *i2c = stmpe->client; 37 : : 38 : 0 : return i2c_smbus_read_i2c_block_data(i2c, reg, length, values); 39 : : } 40 : : 41 : 0 : static int i2c_block_write(struct stmpe *stmpe, u8 reg, u8 length, 42 : : const u8 *values) 43 : : { 44 : 0 : struct i2c_client *i2c = stmpe->client; 45 : : 46 : 0 : return i2c_smbus_write_i2c_block_data(i2c, reg, length, values); 47 : : } 48 : : 49 : : static struct stmpe_client_info i2c_ci = { 50 : : .read_byte = i2c_reg_read, 51 : : .write_byte = i2c_reg_write, 52 : : .read_block = i2c_block_read, 53 : : .write_block = i2c_block_write, 54 : : }; 55 : : 56 : : static const struct of_device_id stmpe_of_match[] = { 57 : : { .compatible = "st,stmpe610", .data = (void *)STMPE610, }, 58 : : { .compatible = "st,stmpe801", .data = (void *)STMPE801, }, 59 : : { .compatible = "st,stmpe811", .data = (void *)STMPE811, }, 60 : : { .compatible = "st,stmpe1600", .data = (void *)STMPE1600, }, 61 : : { .compatible = "st,stmpe1601", .data = (void *)STMPE1601, }, 62 : : { .compatible = "st,stmpe1801", .data = (void *)STMPE1801, }, 63 : : { .compatible = "st,stmpe2401", .data = (void *)STMPE2401, }, 64 : : { .compatible = "st,stmpe2403", .data = (void *)STMPE2403, }, 65 : : {}, 66 : : }; 67 : : MODULE_DEVICE_TABLE(of, stmpe_of_match); 68 : : 69 : : static int 70 : 0 : stmpe_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) 71 : : { 72 : : enum stmpe_partnum partnum; 73 : : const struct of_device_id *of_id; 74 : : 75 : 0 : i2c_ci.data = (void *)id; 76 : 0 : i2c_ci.irq = i2c->irq; 77 : 0 : i2c_ci.client = i2c; 78 : 0 : i2c_ci.dev = &i2c->dev; 79 : : 80 : 0 : of_id = of_match_device(stmpe_of_match, &i2c->dev); 81 : 0 : if (!of_id) { 82 : : /* 83 : : * This happens when the I2C ID matches the node name 84 : : * but no real compatible string has been given. 85 : : */ 86 : 0 : dev_info(&i2c->dev, "matching on node name, compatible is preferred\n"); 87 : 0 : partnum = id->driver_data; 88 : : } else 89 : 0 : partnum = (enum stmpe_partnum)of_id->data; 90 : : 91 : 0 : return stmpe_probe(&i2c_ci, partnum); 92 : : } 93 : : 94 : 0 : static int stmpe_i2c_remove(struct i2c_client *i2c) 95 : : { 96 : : struct stmpe *stmpe = dev_get_drvdata(&i2c->dev); 97 : : 98 : 0 : return stmpe_remove(stmpe); 99 : : } 100 : : 101 : : static const struct i2c_device_id stmpe_i2c_id[] = { 102 : : { "stmpe610", STMPE610 }, 103 : : { "stmpe801", STMPE801 }, 104 : : { "stmpe811", STMPE811 }, 105 : : { "stmpe1600", STMPE1600 }, 106 : : { "stmpe1601", STMPE1601 }, 107 : : { "stmpe1801", STMPE1801 }, 108 : : { "stmpe2401", STMPE2401 }, 109 : : { "stmpe2403", STMPE2403 }, 110 : : { } 111 : : }; 112 : : MODULE_DEVICE_TABLE(i2c, stmpe_id); 113 : : 114 : : static struct i2c_driver stmpe_i2c_driver = { 115 : : .driver = { 116 : : .name = "stmpe-i2c", 117 : : #ifdef CONFIG_PM 118 : : .pm = &stmpe_dev_pm_ops, 119 : : #endif 120 : : .of_match_table = stmpe_of_match, 121 : : }, 122 : : .probe = stmpe_i2c_probe, 123 : : .remove = stmpe_i2c_remove, 124 : : .id_table = stmpe_i2c_id, 125 : : }; 126 : : 127 : 3 : static int __init stmpe_init(void) 128 : : { 129 : 3 : return i2c_add_driver(&stmpe_i2c_driver); 130 : : } 131 : : subsys_initcall(stmpe_init); 132 : : 133 : 0 : static void __exit stmpe_exit(void) 134 : : { 135 : 0 : i2c_del_driver(&stmpe_i2c_driver); 136 : 0 : } 137 : : module_exit(stmpe_exit); 138 : : 139 : : MODULE_LICENSE("GPL v2"); 140 : : MODULE_DESCRIPTION("STMPE MFD I2C Interface Driver"); 141 : : MODULE_AUTHOR("Rabin Vincent <rabin.vincent@stericsson.com>");