]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/mfd/intel_quark_i2c_gpio.c
Merge tag 'v4.1-rc1' into patchwork
[karo-tx-linux.git] / drivers / mfd / intel_quark_i2c_gpio.c
1 /*
2  * Intel Quark MFD PCI driver for I2C & GPIO
3  *
4  * Copyright(c) 2014 Intel Corporation.
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms and conditions of the GNU General Public License,
8  * version 2, as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13  * more details.
14  *
15  * Intel Quark PCI device for I2C and GPIO controller sharing the same
16  * PCI function. This PCI driver will split the 2 devices into their
17  * respective drivers.
18  */
19
20 #include <linux/kernel.h>
21 #include <linux/module.h>
22 #include <linux/pci.h>
23 #include <linux/mfd/core.h>
24 #include <linux/clkdev.h>
25 #include <linux/clk-provider.h>
26 #include <linux/dmi.h>
27 #include <linux/platform_data/gpio-dwapb.h>
28 #include <linux/platform_data/i2c-designware.h>
29
30 /* PCI BAR for register base address */
31 #define MFD_I2C_BAR             0
32 #define MFD_GPIO_BAR            1
33
34 /* The base GPIO number under GPIOLIB framework */
35 #define INTEL_QUARK_MFD_GPIO_BASE       8
36
37 /* The default number of South-Cluster GPIO on Quark. */
38 #define INTEL_QUARK_MFD_NGPIO           8
39
40 /* The DesignWare GPIO ports on Quark. */
41 #define INTEL_QUARK_GPIO_NPORTS 1
42
43 #define INTEL_QUARK_IORES_MEM   0
44 #define INTEL_QUARK_IORES_IRQ   1
45
46 #define INTEL_QUARK_I2C_CONTROLLER_CLK "i2c_designware.0"
47
48 /* The Quark I2C controller source clock */
49 #define INTEL_QUARK_I2C_CLK_HZ  33000000
50
51 #define INTEL_QUARK_I2C_NCLK    1
52
53 struct intel_quark_mfd {
54         struct pci_dev          *pdev;
55         struct clk              *i2c_clk;
56         struct clk_lookup       *i2c_clk_lookup;
57 };
58
59 struct i2c_mode_info {
60         const char *name;
61         unsigned int i2c_scl_freq;
62 };
63
64 static const struct i2c_mode_info platform_i2c_mode_info[] = {
65         {
66                 .name = "Galileo",
67                 .i2c_scl_freq = 100000,
68         },
69         {
70                 .name = "GalileoGen2",
71                 .i2c_scl_freq = 400000,
72         },
73         {}
74 };
75
76 static struct resource intel_quark_i2c_res[] = {
77         [INTEL_QUARK_IORES_MEM] = {
78                 .flags = IORESOURCE_MEM,
79         },
80         [INTEL_QUARK_IORES_IRQ] = {
81                 .flags = IORESOURCE_IRQ,
82         },
83 };
84
85 static struct resource intel_quark_gpio_res[] = {
86         [INTEL_QUARK_IORES_MEM] = {
87                 .flags = IORESOURCE_MEM,
88         },
89 };
90
91 static struct mfd_cell intel_quark_mfd_cells[] = {
92         {
93                 .id = MFD_I2C_BAR,
94                 .name = "i2c_designware",
95                 .num_resources = ARRAY_SIZE(intel_quark_i2c_res),
96                 .resources = intel_quark_i2c_res,
97                 .ignore_resource_conflicts = true,
98         },
99         {
100                 .id = MFD_GPIO_BAR,
101                 .name = "gpio-dwapb",
102                 .num_resources = ARRAY_SIZE(intel_quark_gpio_res),
103                 .resources = intel_quark_gpio_res,
104                 .ignore_resource_conflicts = true,
105         },
106 };
107
108 static const struct pci_device_id intel_quark_mfd_ids[] = {
109         { PCI_VDEVICE(INTEL, 0x0934), },
110         {},
111 };
112 MODULE_DEVICE_TABLE(pci, intel_quark_mfd_ids);
113
114 static int intel_quark_register_i2c_clk(struct intel_quark_mfd *quark_mfd)
115 {
116         struct pci_dev *pdev = quark_mfd->pdev;
117         struct clk_lookup *i2c_clk_lookup;
118         struct clk *i2c_clk;
119         int ret;
120
121         i2c_clk_lookup = devm_kcalloc(&pdev->dev, INTEL_QUARK_I2C_NCLK,
122                                       sizeof(*i2c_clk_lookup), GFP_KERNEL);
123         if (!i2c_clk_lookup)
124                 return -ENOMEM;
125
126         i2c_clk_lookup[0].dev_id = INTEL_QUARK_I2C_CONTROLLER_CLK;
127
128         i2c_clk = clk_register_fixed_rate(&pdev->dev,
129                                           INTEL_QUARK_I2C_CONTROLLER_CLK, NULL,
130                                           CLK_IS_ROOT, INTEL_QUARK_I2C_CLK_HZ);
131
132         quark_mfd->i2c_clk_lookup = i2c_clk_lookup;
133         quark_mfd->i2c_clk = i2c_clk;
134
135         ret = clk_register_clkdevs(i2c_clk, i2c_clk_lookup,
136                                    INTEL_QUARK_I2C_NCLK);
137         if (ret)
138                 dev_err(&pdev->dev, "Fixed clk register failed: %d\n", ret);
139
140         return ret;
141 }
142
143 static void intel_quark_unregister_i2c_clk(struct pci_dev *pdev)
144 {
145         struct intel_quark_mfd *quark_mfd = dev_get_drvdata(&pdev->dev);
146
147         if (!quark_mfd->i2c_clk || !quark_mfd->i2c_clk_lookup)
148                 return;
149
150         clkdev_drop(quark_mfd->i2c_clk_lookup);
151         clk_unregister(quark_mfd->i2c_clk);
152 }
153
154 static int intel_quark_i2c_setup(struct pci_dev *pdev, struct mfd_cell *cell)
155 {
156         const char *board_name = dmi_get_system_info(DMI_BOARD_NAME);
157         const struct i2c_mode_info *info;
158         struct dw_i2c_platform_data *pdata;
159         struct resource *res = (struct resource *)cell->resources;
160         struct device *dev = &pdev->dev;
161
162         res[INTEL_QUARK_IORES_MEM].start =
163                 pci_resource_start(pdev, MFD_I2C_BAR);
164         res[INTEL_QUARK_IORES_MEM].end =
165                 pci_resource_end(pdev, MFD_I2C_BAR);
166
167         res[INTEL_QUARK_IORES_IRQ].start = pdev->irq;
168         res[INTEL_QUARK_IORES_IRQ].end = pdev->irq;
169
170         pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
171         if (!pdata)
172                 return -ENOMEM;
173
174         /* Normal mode by default */
175         pdata->i2c_scl_freq = 100000;
176
177         if (board_name) {
178                 for (info = platform_i2c_mode_info; info->name; info++) {
179                         if (!strcmp(board_name, info->name)) {
180                                 pdata->i2c_scl_freq = info->i2c_scl_freq;
181                                 break;
182                         }
183                 }
184         }
185
186         cell->platform_data = pdata;
187         cell->pdata_size = sizeof(*pdata);
188
189         return 0;
190 }
191
192 static int intel_quark_gpio_setup(struct pci_dev *pdev, struct mfd_cell *cell)
193 {
194         struct dwapb_platform_data *pdata;
195         struct resource *res = (struct resource *)cell->resources;
196         struct device *dev = &pdev->dev;
197
198         res[INTEL_QUARK_IORES_MEM].start =
199                 pci_resource_start(pdev, MFD_GPIO_BAR);
200         res[INTEL_QUARK_IORES_MEM].end =
201                 pci_resource_end(pdev, MFD_GPIO_BAR);
202
203         pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
204         if (!pdata)
205                 return -ENOMEM;
206
207         /* For intel quark x1000, it has only one port: portA */
208         pdata->nports = INTEL_QUARK_GPIO_NPORTS;
209         pdata->properties = devm_kcalloc(dev, pdata->nports,
210                                          sizeof(*pdata->properties),
211                                          GFP_KERNEL);
212         if (!pdata->properties)
213                 return -ENOMEM;
214
215         /* Set the properties for portA */
216         pdata->properties->node         = NULL;
217         pdata->properties->name         = "intel-quark-x1000-gpio-portA";
218         pdata->properties->idx          = 0;
219         pdata->properties->ngpio        = INTEL_QUARK_MFD_NGPIO;
220         pdata->properties->gpio_base    = INTEL_QUARK_MFD_GPIO_BASE;
221         pdata->properties->irq          = pdev->irq;
222         pdata->properties->irq_shared   = true;
223
224         cell->platform_data = pdata;
225         cell->pdata_size = sizeof(*pdata);
226
227         return 0;
228 }
229
230 static int intel_quark_mfd_probe(struct pci_dev *pdev,
231                                  const struct pci_device_id *id)
232 {
233         struct intel_quark_mfd *quark_mfd;
234         int ret;
235
236         ret = pcim_enable_device(pdev);
237         if (ret)
238                 return ret;
239
240         quark_mfd = devm_kzalloc(&pdev->dev, sizeof(*quark_mfd), GFP_KERNEL);
241         if (!quark_mfd)
242                 return -ENOMEM;
243         quark_mfd->pdev = pdev;
244
245         ret = intel_quark_register_i2c_clk(quark_mfd);
246         if (ret)
247                 return ret;
248
249         dev_set_drvdata(&pdev->dev, quark_mfd);
250
251         ret = intel_quark_i2c_setup(pdev, &intel_quark_mfd_cells[MFD_I2C_BAR]);
252         if (ret)
253                 return ret;
254
255         ret = intel_quark_gpio_setup(pdev,
256                                      &intel_quark_mfd_cells[MFD_GPIO_BAR]);
257         if (ret)
258                 return ret;
259
260         return mfd_add_devices(&pdev->dev, 0, intel_quark_mfd_cells,
261                                ARRAY_SIZE(intel_quark_mfd_cells), NULL, 0,
262                                NULL);
263 }
264
265 static void intel_quark_mfd_remove(struct pci_dev *pdev)
266 {
267         intel_quark_unregister_i2c_clk(pdev);
268         mfd_remove_devices(&pdev->dev);
269 }
270
271 static struct pci_driver intel_quark_mfd_driver = {
272         .name           = "intel_quark_mfd_i2c_gpio",
273         .id_table       = intel_quark_mfd_ids,
274         .probe          = intel_quark_mfd_probe,
275         .remove         = intel_quark_mfd_remove,
276 };
277
278 module_pci_driver(intel_quark_mfd_driver);
279
280 MODULE_AUTHOR("Raymond Tan <raymond.tan@intel.com>");
281 MODULE_DESCRIPTION("Intel Quark MFD PCI driver for I2C & GPIO");
282 MODULE_LICENSE("GPL v2");