aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorViresh Kumar <viresh.kumar@st.com>2011-11-17 00:32:20 -0500
committerSamuel Ortiz <sameo@linux.intel.com>2012-01-08 18:37:42 -0500
commit1a6e4b7415339e3b11a87cff0d701b8a2e55f062 (patch)
treefbd5151ac34bf908826f4bbf8b298404660a8de1
parent71e58782d2e054798f91473f5452ffe65e2a5ff8 (diff)
mfd: Separate out STMPE controller and interface specific code
Few STMPE controller can have register interface over SPI or I2C. Current implementation only supports I2C and all code is present in a single file stmpe.c. It would be better to separate out I2C interface specific code from controller specific code. Later SPI specific code can be added in a separate file. This patch separates out I2C and controller specific code into separate files, making stmpe.c independent of I2C. Signed-off-by: Viresh Kumar <viresh.kumar@st.com> Acked-by: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
-rw-r--r--drivers/mfd/Kconfig11
-rw-r--r--drivers/mfd/Makefile1
-rw-r--r--drivers/mfd/stmpe-i2c.c107
-rw-r--r--drivers/mfd/stmpe.c133
-rw-r--r--drivers/mfd/stmpe.h33
-rw-r--r--include/linux/mfd/stmpe.h7
6 files changed, 200 insertions, 92 deletions
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 08a3e087bcea..7bc55819ab4a 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -279,6 +279,17 @@ config MFD_STMPE
279 Keypad: stmpe-keypad 279 Keypad: stmpe-keypad
280 Touchscreen: stmpe-ts 280 Touchscreen: stmpe-ts
281 281
282menu "STMPE Interface Drivers"
283depends on MFD_STMPE
284
285config STMPE_I2C
286 bool "STMPE I2C Inteface"
287 depends on I2C
288 default y
289 help
290 This is used to enable I2C interface of STMPE
291endmenu
292
282config MFD_TC3589X 293config MFD_TC3589X
283 bool "Support Toshiba TC35892 and variants" 294 bool "Support Toshiba TC35892 and variants"
284 depends on I2C=y && GENERIC_HARDIRQS 295 depends on I2C=y && GENERIC_HARDIRQS
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index b2292eb75242..5eb90a70c1a5 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_MFD_DM355EVM_MSP) += dm355evm_msp.o
16obj-$(CONFIG_MFD_TI_SSP) += ti-ssp.o 16obj-$(CONFIG_MFD_TI_SSP) += ti-ssp.o
17 17
18obj-$(CONFIG_MFD_STMPE) += stmpe.o 18obj-$(CONFIG_MFD_STMPE) += stmpe.o
19obj-$(CONFIG_STMPE_I2C) += stmpe-i2c.o
19obj-$(CONFIG_MFD_TC3589X) += tc3589x.o 20obj-$(CONFIG_MFD_TC3589X) += tc3589x.o
20obj-$(CONFIG_MFD_T7L66XB) += t7l66xb.o tmio_core.o 21obj-$(CONFIG_MFD_T7L66XB) += t7l66xb.o tmio_core.o
21obj-$(CONFIG_MFD_TC6387XB) += tc6387xb.o tmio_core.o 22obj-$(CONFIG_MFD_TC6387XB) += tc6387xb.o tmio_core.o
diff --git a/drivers/mfd/stmpe-i2c.c b/drivers/mfd/stmpe-i2c.c
new file mode 100644
index 000000000000..0a4365902e36
--- /dev/null
+++ b/drivers/mfd/stmpe-i2c.c
@@ -0,0 +1,107 @@
1/*
2 * ST Microelectronics MFD: stmpe's i2c client specific driver
3 *
4 * Copyright (C) ST-Ericsson SA 2010
5 * Copyright (C) ST Microelectronics SA 2011
6 *
7 * License Terms: GNU General Public License, version 2
8 * Author: Rabin Vincent <rabin.vincent@stericsson.com> for ST-Ericsson
9 * Author: Viresh Kumar <viresh.kumar@st.com> 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 "stmpe.h"
18
19static int i2c_reg_read(struct stmpe *stmpe, u8 reg)
20{
21 struct i2c_client *i2c = stmpe->client;
22
23 return i2c_smbus_read_byte_data(i2c, reg);
24}
25
26static int i2c_reg_write(struct stmpe *stmpe, u8 reg, u8 val)
27{
28 struct i2c_client *i2c = stmpe->client;
29
30 return i2c_smbus_write_byte_data(i2c, reg, val);
31}
32
33static int i2c_block_read(struct stmpe *stmpe, u8 reg, u8 length, u8 *values)
34{
35 struct i2c_client *i2c = stmpe->client;
36
37 return i2c_smbus_read_i2c_block_data(i2c, reg, length, values);
38}
39
40static int i2c_block_write(struct stmpe *stmpe, u8 reg, u8 length,
41 const u8 *values)
42{
43 struct i2c_client *i2c = stmpe->client;
44
45 return i2c_smbus_write_i2c_block_data(i2c, reg, length, values);
46}
47
48static struct stmpe_client_info i2c_ci = {
49 .read_byte = i2c_reg_read,
50 .write_byte = i2c_reg_write,
51 .read_block = i2c_block_read,
52 .write_block = i2c_block_write,
53};
54
55static int __devinit
56stmpe_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
57{
58 i2c_ci.data = (void *)id;
59 i2c_ci.irq = i2c->irq;
60 i2c_ci.client = i2c;
61 i2c_ci.dev = &i2c->dev;
62
63 return stmpe_probe(&i2c_ci, id->driver_data);
64}
65
66static int __devexit stmpe_i2c_remove(struct i2c_client *i2c)
67{
68 struct stmpe *stmpe = dev_get_drvdata(&i2c->dev);
69
70 return stmpe_remove(stmpe);
71}
72
73static const struct i2c_device_id stmpe_i2c_id[] = {
74 { "stmpe811", STMPE811 },
75 { "stmpe1601", STMPE1601 },
76 { "stmpe2401", STMPE2401 },
77 { "stmpe2403", STMPE2403 },
78 { }
79};
80MODULE_DEVICE_TABLE(i2c, stmpe_id);
81
82static struct i2c_driver stmpe_i2c_driver = {
83 .driver.name = "stmpe-i2c",
84 .driver.owner = THIS_MODULE,
85#ifdef CONFIG_PM
86 .driver.pm = &stmpe_dev_pm_ops,
87#endif
88 .probe = stmpe_i2c_probe,
89 .remove = __devexit_p(stmpe_i2c_remove),
90 .id_table = stmpe_i2c_id,
91};
92
93static int __init stmpe_init(void)
94{
95 return i2c_add_driver(&stmpe_i2c_driver);
96}
97subsys_initcall(stmpe_init);
98
99static void __exit stmpe_exit(void)
100{
101 i2c_del_driver(&stmpe_i2c_driver);
102}
103module_exit(stmpe_exit);
104
105MODULE_LICENSE("GPL v2");
106MODULE_DESCRIPTION("STMPE MFD I2C Interface Driver");
107MODULE_AUTHOR("Rabin Vincent <rabin.vincent@stericsson.com>");
diff --git a/drivers/mfd/stmpe.c b/drivers/mfd/stmpe.c
index 39efa629a19d..83bacde6a7cb 100644
--- a/drivers/mfd/stmpe.c
+++ b/drivers/mfd/stmpe.c
@@ -1,4 +1,6 @@
1/* 1/*
2 * ST Microelectronics MFD: stmpe's driver
3 *
2 * Copyright (C) ST-Ericsson SA 2010 4 * Copyright (C) ST-Ericsson SA 2010
3 * 5 *
4 * License Terms: GNU General Public License, version 2 6 * License Terms: GNU General Public License, version 2
@@ -7,13 +9,11 @@
7 9
8#include <linux/gpio.h> 10#include <linux/gpio.h>
9#include <linux/kernel.h> 11#include <linux/kernel.h>
10#include <linux/module.h>
11#include <linux/interrupt.h> 12#include <linux/interrupt.h>
12#include <linux/irq.h> 13#include <linux/irq.h>
14#include <linux/pm.h>
13#include <linux/slab.h> 15#include <linux/slab.h>
14#include <linux/i2c.h>
15#include <linux/mfd/core.h> 16#include <linux/mfd/core.h>
16#include <linux/mfd/stmpe.h>
17#include "stmpe.h" 17#include "stmpe.h"
18 18
19static int __stmpe_enable(struct stmpe *stmpe, unsigned int blocks) 19static int __stmpe_enable(struct stmpe *stmpe, unsigned int blocks)
@@ -30,10 +30,9 @@ static int __stmpe_reg_read(struct stmpe *stmpe, u8 reg)
30{ 30{
31 int ret; 31 int ret;
32 32
33 ret = i2c_smbus_read_byte_data(stmpe->i2c, reg); 33 ret = stmpe->ci->read_byte(stmpe, reg);
34 if (ret < 0) 34 if (ret < 0)
35 dev_err(stmpe->dev, "failed to read reg %#x: %d\n", 35 dev_err(stmpe->dev, "failed to read reg %#x: %d\n", reg, ret);
36 reg, ret);
37 36
38 dev_vdbg(stmpe->dev, "rd: reg %#x => data %#x\n", reg, ret); 37 dev_vdbg(stmpe->dev, "rd: reg %#x => data %#x\n", reg, ret);
39 38
@@ -46,10 +45,9 @@ static int __stmpe_reg_write(struct stmpe *stmpe, u8 reg, u8 val)
46 45
47 dev_vdbg(stmpe->dev, "wr: reg %#x <= %#x\n", reg, val); 46 dev_vdbg(stmpe->dev, "wr: reg %#x <= %#x\n", reg, val);
48 47
49 ret = i2c_smbus_write_byte_data(stmpe->i2c, reg, val); 48 ret = stmpe->ci->write_byte(stmpe, reg, val);
50 if (ret < 0) 49 if (ret < 0)
51 dev_err(stmpe->dev, "failed to write reg %#x: %d\n", 50 dev_err(stmpe->dev, "failed to write reg %#x: %d\n", reg, ret);
52 reg, ret);
53 51
54 return ret; 52 return ret;
55} 53}
@@ -73,10 +71,9 @@ static int __stmpe_block_read(struct stmpe *stmpe, u8 reg, u8 length,
73{ 71{
74 int ret; 72 int ret;
75 73
76 ret = i2c_smbus_read_i2c_block_data(stmpe->i2c, reg, length, values); 74 ret = stmpe->ci->read_block(stmpe, reg, length, values);
77 if (ret < 0) 75 if (ret < 0)
78 dev_err(stmpe->dev, "failed to read regs %#x: %d\n", 76 dev_err(stmpe->dev, "failed to read regs %#x: %d\n", reg, ret);
79 reg, ret);
80 77
81 dev_vdbg(stmpe->dev, "rd: reg %#x (%d) => ret %#x\n", reg, length, ret); 78 dev_vdbg(stmpe->dev, "rd: reg %#x (%d) => ret %#x\n", reg, length, ret);
82 stmpe_dump_bytes("stmpe rd: ", values, length); 79 stmpe_dump_bytes("stmpe rd: ", values, length);
@@ -92,11 +89,9 @@ static int __stmpe_block_write(struct stmpe *stmpe, u8 reg, u8 length,
92 dev_vdbg(stmpe->dev, "wr: regs %#x (%d)\n", reg, length); 89 dev_vdbg(stmpe->dev, "wr: regs %#x (%d)\n", reg, length);
93 stmpe_dump_bytes("stmpe wr: ", values, length); 90 stmpe_dump_bytes("stmpe wr: ", values, length);
94 91
95 ret = i2c_smbus_write_i2c_block_data(stmpe->i2c, reg, length, 92 ret = stmpe->ci->write_block(stmpe, reg, length, values);
96 values);
97 if (ret < 0) 93 if (ret < 0)
98 dev_err(stmpe->dev, "failed to write regs %#x: %d\n", 94 dev_err(stmpe->dev, "failed to write regs %#x: %d\n", reg, ret);
99 reg, ret);
100 95
101 return ret; 96 return ret;
102} 97}
@@ -874,34 +869,10 @@ static int __devinit stmpe_devices_init(struct stmpe *stmpe)
874 return ret; 869 return ret;
875} 870}
876 871
877#ifdef CONFIG_PM 872/* Called from client specific probe routines */
878static int stmpe_suspend(struct device *dev) 873int stmpe_probe(struct stmpe_client_info *ci, int partnum)
879{
880 struct i2c_client *i2c = to_i2c_client(dev);
881 struct stmpe *stmpe = i2c_get_clientdata(i2c);
882
883 if (device_may_wakeup(&i2c->dev))
884 enable_irq_wake(stmpe->irq);
885
886 return 0;
887}
888
889static int stmpe_resume(struct device *dev)
890{ 874{
891 struct i2c_client *i2c = to_i2c_client(dev); 875 struct stmpe_platform_data *pdata = dev_get_platdata(ci->dev);
892 struct stmpe *stmpe = i2c_get_clientdata(i2c);
893
894 if (device_may_wakeup(&i2c->dev))
895 disable_irq_wake(stmpe->irq);
896
897 return 0;
898}
899#endif
900
901static int __devinit stmpe_probe(struct i2c_client *i2c,
902 const struct i2c_device_id *id)
903{
904 struct stmpe_platform_data *pdata = i2c->dev.platform_data;
905 struct stmpe *stmpe; 876 struct stmpe *stmpe;
906 int ret; 877 int ret;
907 878
@@ -915,18 +886,19 @@ static int __devinit stmpe_probe(struct i2c_client *i2c,
915 mutex_init(&stmpe->irq_lock); 886 mutex_init(&stmpe->irq_lock);
916 mutex_init(&stmpe->lock); 887 mutex_init(&stmpe->lock);
917 888
918 stmpe->dev = &i2c->dev; 889 stmpe->dev = ci->dev;
919 stmpe->i2c = i2c; 890 stmpe->client = ci->client;
920
921 stmpe->pdata = pdata; 891 stmpe->pdata = pdata;
922 stmpe->irq_base = pdata->irq_base; 892 stmpe->irq_base = pdata->irq_base;
923 893 stmpe->ci = ci;
924 stmpe->partnum = id->driver_data; 894 stmpe->partnum = partnum;
925 stmpe->variant = stmpe_variant_info[stmpe->partnum]; 895 stmpe->variant = stmpe_variant_info[partnum];
926 stmpe->regs = stmpe->variant->regs; 896 stmpe->regs = stmpe->variant->regs;
927 stmpe->num_gpios = stmpe->variant->num_gpios; 897 stmpe->num_gpios = stmpe->variant->num_gpios;
898 dev_set_drvdata(stmpe->dev, stmpe);
928 899
929 i2c_set_clientdata(i2c, stmpe); 900 if (ci->init)
901 ci->init(stmpe);
930 902
931 if (pdata->irq_over_gpio) { 903 if (pdata->irq_over_gpio) {
932 ret = gpio_request_one(pdata->irq_gpio, GPIOF_DIR_IN, "stmpe"); 904 ret = gpio_request_one(pdata->irq_gpio, GPIOF_DIR_IN, "stmpe");
@@ -938,7 +910,7 @@ static int __devinit stmpe_probe(struct i2c_client *i2c,
938 910
939 stmpe->irq = gpio_to_irq(pdata->irq_gpio); 911 stmpe->irq = gpio_to_irq(pdata->irq_gpio);
940 } else { 912 } else {
941 stmpe->irq = i2c->irq; 913 stmpe->irq = ci->irq;
942 } 914 }
943 915
944 ret = stmpe_chip_init(stmpe); 916 ret = stmpe_chip_init(stmpe);
@@ -950,8 +922,7 @@ static int __devinit stmpe_probe(struct i2c_client *i2c,
950 goto free_gpio; 922 goto free_gpio;
951 923
952 ret = request_threaded_irq(stmpe->irq, NULL, stmpe_irq, 924 ret = request_threaded_irq(stmpe->irq, NULL, stmpe_irq,
953 pdata->irq_trigger | IRQF_ONESHOT, 925 pdata->irq_trigger | IRQF_ONESHOT, "stmpe", stmpe);
954 "stmpe", stmpe);
955 if (ret) { 926 if (ret) {
956 dev_err(stmpe->dev, "failed to request IRQ: %d\n", ret); 927 dev_err(stmpe->dev, "failed to request IRQ: %d\n", ret);
957 goto out_removeirq; 928 goto out_removeirq;
@@ -978,10 +949,8 @@ out_free:
978 return ret; 949 return ret;
979} 950}
980 951
981static int __devexit stmpe_remove(struct i2c_client *client) 952int stmpe_remove(struct stmpe *stmpe)
982{ 953{
983 struct stmpe *stmpe = i2c_get_clientdata(client);
984
985 mfd_remove_devices(stmpe->dev); 954 mfd_remove_devices(stmpe->dev);
986 955
987 free_irq(stmpe->irq, stmpe); 956 free_irq(stmpe->irq, stmpe);
@@ -995,45 +964,29 @@ static int __devexit stmpe_remove(struct i2c_client *client)
995 return 0; 964 return 0;
996} 965}
997 966
998static const struct i2c_device_id stmpe_id[] = {
999 { "stmpe811", STMPE811 },
1000 { "stmpe1601", STMPE1601 },
1001 { "stmpe2401", STMPE2401 },
1002 { "stmpe2403", STMPE2403 },
1003 { }
1004};
1005MODULE_DEVICE_TABLE(i2c, stmpe_id);
1006
1007#ifdef CONFIG_PM 967#ifdef CONFIG_PM
1008static const struct dev_pm_ops stmpe_dev_pm_ops = { 968static int stmpe_suspend(struct device *dev)
1009 .suspend = stmpe_suspend, 969{
1010 .resume = stmpe_resume, 970 struct stmpe *stmpe = dev_get_drvdata(dev);
1011};
1012#endif
1013 971
1014static struct i2c_driver stmpe_driver = { 972 if (device_may_wakeup(dev))
1015 .driver.name = "stmpe", 973 enable_irq_wake(stmpe->irq);
1016 .driver.owner = THIS_MODULE,
1017#ifdef CONFIG_PM
1018 .driver.pm = &stmpe_dev_pm_ops,
1019#endif
1020 .probe = stmpe_probe,
1021 .remove = __devexit_p(stmpe_remove),
1022 .id_table = stmpe_id,
1023};
1024 974
1025static int __init stmpe_init(void) 975 return 0;
1026{
1027 return i2c_add_driver(&stmpe_driver);
1028} 976}
1029subsys_initcall(stmpe_init);
1030 977
1031static void __exit stmpe_exit(void) 978static int stmpe_resume(struct device *dev)
1032{ 979{
1033 i2c_del_driver(&stmpe_driver); 980 struct stmpe *stmpe = dev_get_drvdata(dev);
981
982 if (device_may_wakeup(dev))
983 disable_irq_wake(stmpe->irq);
984
985 return 0;
1034} 986}
1035module_exit(stmpe_exit);
1036 987
1037MODULE_LICENSE("GPL v2"); 988const struct dev_pm_ops stmpe_dev_pm_ops = {
1038MODULE_DESCRIPTION("STMPE MFD core driver"); 989 .suspend = stmpe_suspend,
1039MODULE_AUTHOR("Rabin Vincent <rabin.vincent@stericsson.com>"); 990 .resume = stmpe_resume,
991};
992#endif
diff --git a/drivers/mfd/stmpe.h b/drivers/mfd/stmpe.h
index e4ee38956583..18d89a68ce40 100644
--- a/drivers/mfd/stmpe.h
+++ b/drivers/mfd/stmpe.h
@@ -8,6 +8,14 @@
8#ifndef __STMPE_H 8#ifndef __STMPE_H
9#define __STMPE_H 9#define __STMPE_H
10 10
11#include <linux/device.h>
12#include <linux/mfd/core.h>
13#include <linux/mfd/stmpe.h>
14#include <linux/printk.h>
15#include <linux/types.h>
16
17extern const struct dev_pm_ops stmpe_dev_pm_ops;
18
11#ifdef STMPE_DUMP_BYTES 19#ifdef STMPE_DUMP_BYTES
12static inline void stmpe_dump_bytes(const char *str, const void *buf, 20static inline void stmpe_dump_bytes(const char *str, const void *buf,
13 size_t len) 21 size_t len)
@@ -67,6 +75,31 @@ struct stmpe_variant_info {
67 int (*enable_autosleep)(struct stmpe *stmpe, int autosleep_timeout); 75 int (*enable_autosleep)(struct stmpe *stmpe, int autosleep_timeout);
68}; 76};
69 77
78/**
79 * struct stmpe_client_info - i2c or spi specific routines/info
80 * @data: client specific data
81 * @read_byte: read single byte
82 * @write_byte: write single byte
83 * @read_block: read block or multiple bytes
84 * @write_block: write block or multiple bytes
85 * @init: client init routine, called during probe
86 */
87struct stmpe_client_info {
88 void *data;
89 int irq;
90 void *client;
91 struct device *dev;
92 int (*read_byte)(struct stmpe *stmpe, u8 reg);
93 int (*write_byte)(struct stmpe *stmpe, u8 reg, u8 val);
94 int (*read_block)(struct stmpe *stmpe, u8 reg, u8 len, u8 *values);
95 int (*write_block)(struct stmpe *stmpe, u8 reg, u8 len,
96 const u8 *values);
97 void (*init)(struct stmpe *stmpe);
98};
99
100int stmpe_probe(struct stmpe_client_info *ci, int partnum);
101int stmpe_remove(struct stmpe *stmpe);
102
70#define STMPE_ICR_LSB_HIGH (1 << 2) 103#define STMPE_ICR_LSB_HIGH (1 << 2)
71#define STMPE_ICR_LSB_EDGE (1 << 1) 104#define STMPE_ICR_LSB_EDGE (1 << 1)
72#define STMPE_ICR_LSB_GIM (1 << 0) 105#define STMPE_ICR_LSB_GIM (1 << 0)
diff --git a/include/linux/mfd/stmpe.h b/include/linux/mfd/stmpe.h
index 270d6613aadf..babc6b2857d3 100644
--- a/include/linux/mfd/stmpe.h
+++ b/include/linux/mfd/stmpe.h
@@ -50,13 +50,15 @@ enum {
50 50
51 51
52struct stmpe_variant_info; 52struct stmpe_variant_info;
53struct stmpe_client_info;
53 54
54/** 55/**
55 * struct stmpe - STMPE MFD structure 56 * struct stmpe - STMPE MFD structure
56 * @lock: lock protecting I/O operations 57 * @lock: lock protecting I/O operations
57 * @irq_lock: IRQ bus lock 58 * @irq_lock: IRQ bus lock
58 * @dev: device, mostly for dev_dbg() 59 * @dev: device, mostly for dev_dbg()
59 * @i2c: i2c client 60 * @client: client - i2c or spi
61 * @ci: client specific information
60 * @partnum: part number 62 * @partnum: part number
61 * @variant: the detected STMPE model number 63 * @variant: the detected STMPE model number
62 * @regs: list of addresses of registers which are at different addresses on 64 * @regs: list of addresses of registers which are at different addresses on
@@ -72,7 +74,8 @@ struct stmpe {
72 struct mutex lock; 74 struct mutex lock;
73 struct mutex irq_lock; 75 struct mutex irq_lock;
74 struct device *dev; 76 struct device *dev;
75 struct i2c_client *i2c; 77 void *client;
78 struct stmpe_client_info *ci;
76 enum stmpe_partnum partnum; 79 enum stmpe_partnum partnum;
77 struct stmpe_variant_info *variant; 80 struct stmpe_variant_info *variant;
78 const u8 *regs; 81 const u8 *regs;