diff options
author | Viresh Kumar <viresh.kumar@st.com> | 2011-11-17 00:32:20 -0500 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2012-01-08 18:37:42 -0500 |
commit | 1a6e4b7415339e3b11a87cff0d701b8a2e55f062 (patch) | |
tree | fbd5151ac34bf908826f4bbf8b298404660a8de1 /drivers/mfd/stmpe.c | |
parent | 71e58782d2e054798f91473f5452ffe65e2a5ff8 (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>
Diffstat (limited to 'drivers/mfd/stmpe.c')
-rw-r--r-- | drivers/mfd/stmpe.c | 133 |
1 files changed, 43 insertions, 90 deletions
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 | ||
19 | static int __stmpe_enable(struct stmpe *stmpe, unsigned int blocks) | 19 | static 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 */ |
878 | static int stmpe_suspend(struct device *dev) | 873 | int 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 | |||
889 | static 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 | |||
901 | static 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 | ||
981 | static int __devexit stmpe_remove(struct i2c_client *client) | 952 | int 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 | ||
998 | static const struct i2c_device_id stmpe_id[] = { | ||
999 | { "stmpe811", STMPE811 }, | ||
1000 | { "stmpe1601", STMPE1601 }, | ||
1001 | { "stmpe2401", STMPE2401 }, | ||
1002 | { "stmpe2403", STMPE2403 }, | ||
1003 | { } | ||
1004 | }; | ||
1005 | MODULE_DEVICE_TABLE(i2c, stmpe_id); | ||
1006 | |||
1007 | #ifdef CONFIG_PM | 967 | #ifdef CONFIG_PM |
1008 | static const struct dev_pm_ops stmpe_dev_pm_ops = { | 968 | static 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 | ||
1014 | static 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 | ||
1025 | static int __init stmpe_init(void) | 975 | return 0; |
1026 | { | ||
1027 | return i2c_add_driver(&stmpe_driver); | ||
1028 | } | 976 | } |
1029 | subsys_initcall(stmpe_init); | ||
1030 | 977 | ||
1031 | static void __exit stmpe_exit(void) | 978 | static 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 | } |
1035 | module_exit(stmpe_exit); | ||
1036 | 987 | ||
1037 | MODULE_LICENSE("GPL v2"); | 988 | const struct dev_pm_ops stmpe_dev_pm_ops = { |
1038 | MODULE_DESCRIPTION("STMPE MFD core driver"); | 989 | .suspend = stmpe_suspend, |
1039 | MODULE_AUTHOR("Rabin Vincent <rabin.vincent@stericsson.com>"); | 990 | .resume = stmpe_resume, |
991 | }; | ||
992 | #endif | ||