0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/i2c.h>
0010 #include <linux/interrupt.h>
0011 #include <linux/mfd/core.h>
0012 #include <linux/mfd/max77714.h>
0013 #include <linux/module.h>
0014 #include <linux/of.h>
0015 #include <linux/regmap.h>
0016
0017 static const struct mfd_cell max77714_cells[] = {
0018 { .name = "max77714-watchdog" },
0019 { .name = "max77714-rtc" },
0020 };
0021
0022 static const struct regmap_range max77714_readable_ranges[] = {
0023 regmap_reg_range(MAX77714_INT_TOP, MAX77714_INT_TOP),
0024 regmap_reg_range(MAX77714_INT_TOPM, MAX77714_INT_TOPM),
0025 regmap_reg_range(MAX77714_32K_STATUS, MAX77714_32K_CONFIG),
0026 regmap_reg_range(MAX77714_CNFG_GLBL2, MAX77714_CNFG2_ONOFF),
0027 };
0028
0029 static const struct regmap_range max77714_writable_ranges[] = {
0030 regmap_reg_range(MAX77714_INT_TOPM, MAX77714_INT_TOPM),
0031 regmap_reg_range(MAX77714_32K_CONFIG, MAX77714_32K_CONFIG),
0032 regmap_reg_range(MAX77714_CNFG_GLBL2, MAX77714_CNFG2_ONOFF),
0033 };
0034
0035 static const struct regmap_access_table max77714_readable_table = {
0036 .yes_ranges = max77714_readable_ranges,
0037 .n_yes_ranges = ARRAY_SIZE(max77714_readable_ranges),
0038 };
0039
0040 static const struct regmap_access_table max77714_writable_table = {
0041 .yes_ranges = max77714_writable_ranges,
0042 .n_yes_ranges = ARRAY_SIZE(max77714_writable_ranges),
0043 };
0044
0045 static const struct regmap_config max77714_regmap_config = {
0046 .reg_bits = 8,
0047 .val_bits = 8,
0048 .max_register = MAX77714_CNFG2_ONOFF,
0049 .rd_table = &max77714_readable_table,
0050 .wr_table = &max77714_writable_table,
0051 };
0052
0053 static const struct regmap_irq max77714_top_irqs[] = {
0054 REGMAP_IRQ_REG(MAX77714_IRQ_TOP_ONOFF, 0, MAX77714_INT_TOP_ONOFF),
0055 REGMAP_IRQ_REG(MAX77714_IRQ_TOP_RTC, 0, MAX77714_INT_TOP_RTC),
0056 REGMAP_IRQ_REG(MAX77714_IRQ_TOP_GPIO, 0, MAX77714_INT_TOP_GPIO),
0057 REGMAP_IRQ_REG(MAX77714_IRQ_TOP_LDO, 0, MAX77714_INT_TOP_LDO),
0058 REGMAP_IRQ_REG(MAX77714_IRQ_TOP_SD, 0, MAX77714_INT_TOP_SD),
0059 REGMAP_IRQ_REG(MAX77714_IRQ_TOP_GLBL, 0, MAX77714_INT_TOP_GLBL),
0060 };
0061
0062 static const struct regmap_irq_chip max77714_irq_chip = {
0063 .name = "max77714-pmic",
0064 .status_base = MAX77714_INT_TOP,
0065 .mask_base = MAX77714_INT_TOPM,
0066 .num_regs = 1,
0067 .irqs = max77714_top_irqs,
0068 .num_irqs = ARRAY_SIZE(max77714_top_irqs),
0069 };
0070
0071
0072
0073
0074
0075
0076 static int max77714_setup_xosc(struct device *dev, struct regmap *regmap)
0077 {
0078
0079 static const unsigned int load_cap[4] = {0, 10, 12, 22};
0080 unsigned int load_cap_idx;
0081 unsigned int status;
0082 int err;
0083
0084 err = regmap_update_bits(regmap, MAX77714_32K_CONFIG,
0085 MAX77714_32K_CONFIG_XOSC_RETRY,
0086 MAX77714_32K_CONFIG_XOSC_RETRY);
0087 if (err)
0088 return dev_err_probe(dev, err, "Failed to configure the external oscillator\n");
0089
0090 err = regmap_read(regmap, MAX77714_32K_STATUS, &status);
0091 if (err)
0092 return dev_err_probe(dev, err, "Failed to read external oscillator status\n");
0093
0094 load_cap_idx = (status >> MAX77714_32K_STATUS_32KLOAD_SHF)
0095 & MAX77714_32K_STATUS_32KLOAD_MSK;
0096
0097 dev_info(dev, "Using %s oscillator, %d pF load cap\n",
0098 status & MAX77714_32K_STATUS_32KSOURCE ? "internal" : "external",
0099 load_cap[load_cap_idx]);
0100
0101 return 0;
0102 }
0103
0104 static int max77714_probe(struct i2c_client *client)
0105 {
0106 struct device *dev = &client->dev;
0107 struct regmap *regmap;
0108 struct regmap_irq_chip_data *irq_data;
0109 int err;
0110
0111 regmap = devm_regmap_init_i2c(client, &max77714_regmap_config);
0112 if (IS_ERR(regmap))
0113 return dev_err_probe(dev, PTR_ERR(regmap),
0114 "Failed to initialise regmap\n");
0115
0116 err = max77714_setup_xosc(dev, regmap);
0117 if (err)
0118 return err;
0119
0120 err = devm_regmap_add_irq_chip(dev, regmap, client->irq,
0121 IRQF_ONESHOT | IRQF_SHARED, 0,
0122 &max77714_irq_chip, &irq_data);
0123 if (err)
0124 return dev_err_probe(dev, err, "Failed to add PMIC IRQ chip\n");
0125
0126 err = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE,
0127 max77714_cells, ARRAY_SIZE(max77714_cells),
0128 NULL, 0, NULL);
0129 if (err)
0130 return dev_err_probe(dev, err, "Failed to register child devices\n");
0131
0132 return 0;
0133 }
0134
0135 static const struct of_device_id max77714_dt_match[] = {
0136 { .compatible = "maxim,max77714" },
0137 {},
0138 };
0139 MODULE_DEVICE_TABLE(of, max77714_dt_match);
0140
0141 static struct i2c_driver max77714_driver = {
0142 .driver = {
0143 .name = "max77714",
0144 .of_match_table = max77714_dt_match,
0145 },
0146 .probe_new = max77714_probe,
0147 };
0148 module_i2c_driver(max77714_driver);
0149
0150 MODULE_DESCRIPTION("Maxim MAX77714 MFD core driver");
0151 MODULE_AUTHOR("Luca Ceresoli <luca.ceresoli@bootlin.com>");
0152 MODULE_LICENSE("GPL");