0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/kernel.h>
0013 #include <linux/module.h>
0014 #include <linux/pci.h>
0015 #include <linux/mfd/core.h>
0016 #include <linux/clkdev.h>
0017 #include <linux/clk-provider.h>
0018 #include <linux/dmi.h>
0019 #include <linux/i2c.h>
0020 #include <linux/property.h>
0021
0022
0023 #define MFD_I2C_BAR 0
0024 #define MFD_GPIO_BAR 1
0025
0026
0027 #define MFD_ACPI_MATCH_GPIO 0ULL
0028 #define MFD_ACPI_MATCH_I2C 1ULL
0029
0030 #define INTEL_QUARK_IORES_MEM 0
0031 #define INTEL_QUARK_IORES_IRQ 1
0032
0033 #define INTEL_QUARK_I2C_CONTROLLER_CLK "i2c_designware.0"
0034
0035
0036 #define INTEL_QUARK_I2C_CLK_HZ 33000000
0037
0038 struct intel_quark_mfd {
0039 struct clk *i2c_clk;
0040 struct clk_lookup *i2c_clk_lookup;
0041 };
0042
0043 static const struct property_entry intel_quark_i2c_controller_standard_properties[] = {
0044 PROPERTY_ENTRY_U32("clock-frequency", I2C_MAX_STANDARD_MODE_FREQ),
0045 { }
0046 };
0047
0048 static const struct software_node intel_quark_i2c_controller_standard_node = {
0049 .name = "intel-quark-i2c-controller",
0050 .properties = intel_quark_i2c_controller_standard_properties,
0051 };
0052
0053 static const struct property_entry intel_quark_i2c_controller_fast_properties[] = {
0054 PROPERTY_ENTRY_U32("clock-frequency", I2C_MAX_FAST_MODE_FREQ),
0055 { }
0056 };
0057
0058 static const struct software_node intel_quark_i2c_controller_fast_node = {
0059 .name = "intel-quark-i2c-controller",
0060 .properties = intel_quark_i2c_controller_fast_properties,
0061 };
0062
0063 static const struct dmi_system_id dmi_platform_info[] = {
0064 {
0065 .matches = {
0066 DMI_EXACT_MATCH(DMI_BOARD_NAME, "Galileo"),
0067 },
0068 .driver_data = (void *)&intel_quark_i2c_controller_standard_node,
0069 },
0070 {
0071 .matches = {
0072 DMI_EXACT_MATCH(DMI_BOARD_NAME, "GalileoGen2"),
0073 },
0074 .driver_data = (void *)&intel_quark_i2c_controller_fast_node,
0075 },
0076 {
0077 .matches = {
0078 DMI_EXACT_MATCH(DMI_BOARD_NAME, "SIMATIC IOT2000"),
0079 },
0080 .driver_data = (void *)&intel_quark_i2c_controller_fast_node,
0081 },
0082 {}
0083 };
0084
0085
0086 static struct resource intel_quark_i2c_res[] = {
0087 [INTEL_QUARK_IORES_MEM] = {
0088 .flags = IORESOURCE_MEM,
0089 },
0090 [INTEL_QUARK_IORES_IRQ] = {
0091 .flags = IORESOURCE_IRQ,
0092 },
0093 };
0094
0095 static struct mfd_cell_acpi_match intel_quark_acpi_match_i2c = {
0096 .adr = MFD_ACPI_MATCH_I2C,
0097 };
0098
0099
0100 static struct resource intel_quark_gpio_res[] = {
0101 [INTEL_QUARK_IORES_MEM] = {
0102 .flags = IORESOURCE_MEM,
0103 },
0104 [INTEL_QUARK_IORES_IRQ] = {
0105 .flags = IORESOURCE_IRQ,
0106 },
0107 };
0108
0109 static struct mfd_cell_acpi_match intel_quark_acpi_match_gpio = {
0110 .adr = MFD_ACPI_MATCH_GPIO,
0111 };
0112
0113 static const struct software_node intel_quark_gpio_controller_node = {
0114 .name = "intel-quark-gpio-controller",
0115 };
0116
0117 static const struct property_entry intel_quark_gpio_portA_properties[] = {
0118 PROPERTY_ENTRY_U32("reg", 0),
0119 PROPERTY_ENTRY_U32("snps,nr-gpios", 8),
0120 PROPERTY_ENTRY_U32("gpio-base", 8),
0121 { }
0122 };
0123
0124 static const struct software_node intel_quark_gpio_portA_node = {
0125 .name = "portA",
0126 .parent = &intel_quark_gpio_controller_node,
0127 .properties = intel_quark_gpio_portA_properties,
0128 };
0129
0130 static const struct software_node *intel_quark_gpio_node_group[] = {
0131 &intel_quark_gpio_controller_node,
0132 &intel_quark_gpio_portA_node,
0133 NULL
0134 };
0135
0136 static struct mfd_cell intel_quark_mfd_cells[] = {
0137 [MFD_I2C_BAR] = {
0138 .id = MFD_I2C_BAR,
0139 .name = "i2c_designware",
0140 .acpi_match = &intel_quark_acpi_match_i2c,
0141 .num_resources = ARRAY_SIZE(intel_quark_i2c_res),
0142 .resources = intel_quark_i2c_res,
0143 .ignore_resource_conflicts = true,
0144 },
0145 [MFD_GPIO_BAR] = {
0146 .id = MFD_GPIO_BAR,
0147 .name = "gpio-dwapb",
0148 .acpi_match = &intel_quark_acpi_match_gpio,
0149 .num_resources = ARRAY_SIZE(intel_quark_gpio_res),
0150 .resources = intel_quark_gpio_res,
0151 .ignore_resource_conflicts = true,
0152 },
0153 };
0154
0155 static const struct pci_device_id intel_quark_mfd_ids[] = {
0156 { PCI_VDEVICE(INTEL, 0x0934), },
0157 {},
0158 };
0159 MODULE_DEVICE_TABLE(pci, intel_quark_mfd_ids);
0160
0161 static int intel_quark_register_i2c_clk(struct device *dev)
0162 {
0163 struct intel_quark_mfd *quark_mfd = dev_get_drvdata(dev);
0164 struct clk *i2c_clk;
0165
0166 i2c_clk = clk_register_fixed_rate(dev,
0167 INTEL_QUARK_I2C_CONTROLLER_CLK, NULL,
0168 0, INTEL_QUARK_I2C_CLK_HZ);
0169 if (IS_ERR(i2c_clk))
0170 return PTR_ERR(i2c_clk);
0171
0172 quark_mfd->i2c_clk = i2c_clk;
0173 quark_mfd->i2c_clk_lookup = clkdev_create(i2c_clk, NULL,
0174 INTEL_QUARK_I2C_CONTROLLER_CLK);
0175
0176 if (!quark_mfd->i2c_clk_lookup) {
0177 clk_unregister(quark_mfd->i2c_clk);
0178 dev_err(dev, "Fixed clk register failed\n");
0179 return -ENOMEM;
0180 }
0181
0182 return 0;
0183 }
0184
0185 static void intel_quark_unregister_i2c_clk(struct device *dev)
0186 {
0187 struct intel_quark_mfd *quark_mfd = dev_get_drvdata(dev);
0188
0189 if (!quark_mfd->i2c_clk_lookup)
0190 return;
0191
0192 clkdev_drop(quark_mfd->i2c_clk_lookup);
0193 clk_unregister(quark_mfd->i2c_clk);
0194 }
0195
0196 static int intel_quark_i2c_setup(struct pci_dev *pdev)
0197 {
0198 struct mfd_cell *cell = &intel_quark_mfd_cells[MFD_I2C_BAR];
0199 struct resource *res = intel_quark_i2c_res;
0200 const struct dmi_system_id *dmi_id;
0201
0202 res[INTEL_QUARK_IORES_MEM].start = pci_resource_start(pdev, MFD_I2C_BAR);
0203 res[INTEL_QUARK_IORES_MEM].end = pci_resource_end(pdev, MFD_I2C_BAR);
0204
0205 res[INTEL_QUARK_IORES_IRQ].start = pci_irq_vector(pdev, 0);
0206 res[INTEL_QUARK_IORES_IRQ].end = pci_irq_vector(pdev, 0);
0207
0208
0209 cell->swnode = &intel_quark_i2c_controller_standard_node;
0210
0211 dmi_id = dmi_first_match(dmi_platform_info);
0212 if (dmi_id)
0213 cell->swnode = (struct software_node *)dmi_id->driver_data;
0214
0215 return 0;
0216 }
0217
0218 static int intel_quark_gpio_setup(struct pci_dev *pdev)
0219 {
0220 struct mfd_cell *cell = &intel_quark_mfd_cells[MFD_GPIO_BAR];
0221 struct resource *res = intel_quark_gpio_res;
0222 int ret;
0223
0224 res[INTEL_QUARK_IORES_MEM].start = pci_resource_start(pdev, MFD_GPIO_BAR);
0225 res[INTEL_QUARK_IORES_MEM].end = pci_resource_end(pdev, MFD_GPIO_BAR);
0226
0227 res[INTEL_QUARK_IORES_IRQ].start = pci_irq_vector(pdev, 0);
0228 res[INTEL_QUARK_IORES_IRQ].end = pci_irq_vector(pdev, 0);
0229
0230 ret = software_node_register_node_group(intel_quark_gpio_node_group);
0231 if (ret)
0232 return ret;
0233
0234 cell->swnode = &intel_quark_gpio_controller_node;
0235 return 0;
0236 }
0237
0238 static int intel_quark_mfd_probe(struct pci_dev *pdev,
0239 const struct pci_device_id *id)
0240 {
0241 struct intel_quark_mfd *quark_mfd;
0242 int ret;
0243
0244 ret = pcim_enable_device(pdev);
0245 if (ret)
0246 return ret;
0247
0248 quark_mfd = devm_kzalloc(&pdev->dev, sizeof(*quark_mfd), GFP_KERNEL);
0249 if (!quark_mfd)
0250 return -ENOMEM;
0251
0252 dev_set_drvdata(&pdev->dev, quark_mfd);
0253
0254 ret = intel_quark_register_i2c_clk(&pdev->dev);
0255 if (ret)
0256 return ret;
0257
0258 pci_set_master(pdev);
0259
0260
0261 ret = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
0262 if (ret < 0)
0263 goto err_unregister_i2c_clk;
0264
0265 ret = intel_quark_i2c_setup(pdev);
0266 if (ret)
0267 goto err_free_irq_vectors;
0268
0269 ret = intel_quark_gpio_setup(pdev);
0270 if (ret)
0271 goto err_free_irq_vectors;
0272
0273 ret = mfd_add_devices(&pdev->dev, 0, intel_quark_mfd_cells,
0274 ARRAY_SIZE(intel_quark_mfd_cells), NULL, 0,
0275 NULL);
0276 if (ret)
0277 goto err_unregister_gpio_node_group;
0278
0279 return 0;
0280
0281 err_unregister_gpio_node_group:
0282 software_node_unregister_node_group(intel_quark_gpio_node_group);
0283 err_free_irq_vectors:
0284 pci_free_irq_vectors(pdev);
0285 err_unregister_i2c_clk:
0286 intel_quark_unregister_i2c_clk(&pdev->dev);
0287 return ret;
0288 }
0289
0290 static void intel_quark_mfd_remove(struct pci_dev *pdev)
0291 {
0292 mfd_remove_devices(&pdev->dev);
0293 software_node_unregister_node_group(intel_quark_gpio_node_group);
0294 pci_free_irq_vectors(pdev);
0295 intel_quark_unregister_i2c_clk(&pdev->dev);
0296 }
0297
0298 static struct pci_driver intel_quark_mfd_driver = {
0299 .name = "intel_quark_mfd_i2c_gpio",
0300 .id_table = intel_quark_mfd_ids,
0301 .probe = intel_quark_mfd_probe,
0302 .remove = intel_quark_mfd_remove,
0303 };
0304
0305 module_pci_driver(intel_quark_mfd_driver);
0306
0307 MODULE_AUTHOR("Raymond Tan <raymond.tan@intel.com>");
0308 MODULE_DESCRIPTION("Intel Quark MFD PCI driver for I2C & GPIO");
0309 MODULE_LICENSE("GPL v2");