static int device_irq_init_805(struct pm80x_chip *chip) { struct regmap *map = chip->regmap; unsigned long flags = IRQF_ONESHOT; int data, mask, ret = -EINVAL; if (!map || !chip->irq) { dev_err(chip->dev, "incorrect parameters\n"); return -EINVAL; } /* * irq_mode defines the way of clearing interrupt. it's read-clear by * default. */ mask = PM805_STATUS0_INT_CLEAR | PM805_STATUS0_INV_INT | PM800_STATUS0_INT_MASK; data = PM805_STATUS0_INT_CLEAR; ret = regmap_update_bits(map, PM805_INT_STATUS0, mask, data); /* * PM805_INT_STATUS is under 32K clock domain, so need to * add proper delay before the next I2C register access. */ usleep_range(1000, 3000); if (ret < 0) goto out; ret = regmap_add_irq_chip(chip->regmap, chip->irq, flags, -1, chip->regmap_irq_chip, &chip->irq_data); out: return ret; }
static int device_irq_init_830(struct pm830_chip *chip) { struct regmap *map = chip->regmap; unsigned long flags = chip->irq_flags; int data, mask, ret = -EINVAL; if (!map || !chip->irq) { dev_err(chip->dev, "incorrect parameters\n"); return -EINVAL; } /* * the way of clearing interrupt: * it's read-clear by default, leave as it is; */ mask = PM830_INT_CLEAR | PM830_INV_INT | PM830_INT_MASK; data = (0 << 1); /* * interrupt is set only when the enable bit is set * interrupt active low and read cleared */ ret = regmap_update_bits(map, PM830_MISC1, mask, data); if (ret < 0) goto out; /* read to clear the interrupt status registers */ regmap_read(map, PM830_INT_STATUS1, &data); regmap_read(map, PM830_INT_STATUS2, &data); ret = regmap_add_irq_chip(chip->regmap, chip->irq, flags, -1, chip->regmap_irq_chip, &chip->irq_data); out: return ret; }
int arizona_irq_init(struct arizona *arizona) { int flags = IRQF_ONESHOT; int ret, i; struct regmap_irq_chip *aod, *irq; bool ctrlif_error = true; int irq_base; struct irq_data *irq_data; switch (arizona->type) { #ifdef CONFIG_MFD_WM5102 case WM5102: aod = &wm5102_aod; irq = &wm5102_irq; ctrlif_error = false; break; #endif #ifdef CONFIG_MFD_WM5110 case WM5110: aod = &wm5110_aod; irq = &wm5110_irq; ctrlif_error = false; break; #endif default: BUG_ON("Unknown Arizona class device" == NULL); return -EINVAL; } /* Disable all wake sources by default */ regmap_write(arizona->regmap, ARIZONA_WAKE_CONTROL, 0); /* Read the flags from the interrupt controller if not specified */ if (!arizona->pdata.irq_flags) { irq_data = irq_get_irq_data(arizona->irq); if (!irq_data) { dev_err(arizona->dev, "Invalid IRQ: %d\n", arizona->irq); return -EINVAL; } arizona->pdata.irq_flags = irqd_get_trigger_type(irq_data); switch (arizona->pdata.irq_flags) { case IRQF_TRIGGER_LOW: case IRQF_TRIGGER_HIGH: case IRQF_TRIGGER_RISING: case IRQF_TRIGGER_FALLING: break; case IRQ_TYPE_NONE: default: /* Device default */ arizona->pdata.irq_flags = IRQF_TRIGGER_LOW; break; } } if (arizona->pdata.irq_flags & (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_RISING)) { ret = regmap_update_bits(arizona->regmap, ARIZONA_IRQ_CTRL_1, ARIZONA_IRQ_POL, 0); if (ret != 0) { dev_err(arizona->dev, "Couldn't set IRQ polarity: %d\n", ret); goto err; } } flags |= arizona->pdata.irq_flags; /* set up virtual IRQs */ irq_base = irq_alloc_descs(arizona->pdata.irq_base, 0, ARRAY_SIZE(arizona->virq), 0); if (irq_base < 0) { dev_warn(arizona->dev, "Failed to allocate IRQs: %d\n", irq_base); return irq_base; } arizona->virq[0] = irq_base; arizona->virq[1] = irq_base + 1; irq_base += 2; for (i = 0; i < ARRAY_SIZE(arizona->virq); i++) { irq_set_chip_and_handler(arizona->virq[i], &arizona_irq_chip, handle_edge_irq); irq_set_nested_thread(arizona->virq[i], 1); /* ARM needs us to explicitly flag the IRQ as valid * and will set them noprobe when we do so. */ #ifdef CONFIG_ARM set_irq_flags(arizona->virq[i], IRQF_VALID); #else irq_set_noprobe(arizona->virq[i]); #endif } ret = regmap_add_irq_chip(arizona->regmap, arizona->virq[0], IRQF_ONESHOT, irq_base, aod, &arizona->aod_irq_chip); if (ret != 0) { dev_err(arizona->dev, "Failed to add AOD IRQs: %d\n", ret); goto err_domain; } ret = regmap_add_irq_chip(arizona->regmap, arizona->virq[1], IRQF_ONESHOT, irq_base + ARIZONA_NUM_IRQ, irq, &arizona->irq_chip); if (ret != 0) { dev_err(arizona->dev, "Failed to add IRQs: %d\n", ret); goto err_aod; } /* Make sure the boot done IRQ is unmasked for resumes */ i = arizona_map_irq(arizona, ARIZONA_IRQ_BOOT_DONE); ret = request_threaded_irq(i, NULL, arizona_boot_done, IRQF_ONESHOT, "Boot done", arizona); if (ret != 0) { dev_err(arizona->dev, "Failed to request boot done %d: %d\n", arizona->irq, ret); goto err_boot_done; } /* Handle control interface errors in the core */ if (ctrlif_error) { i = arizona_map_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR); ret = request_threaded_irq(i, NULL, arizona_ctrlif_err, IRQF_ONESHOT, "Control interface error", arizona); if (ret != 0) { dev_err(arizona->dev, "Failed to request CTRLIF_ERR %d: %d\n", arizona->irq, ret); goto err_ctrlif; } } /* Used to emulate edge trigger and to work around broken pinmux */ if (arizona->pdata.irq_gpio) { if (gpio_to_irq(arizona->pdata.irq_gpio) != arizona->irq) { dev_warn(arizona->dev, "IRQ %d is not GPIO %d (%d)\n", arizona->irq, arizona->pdata.irq_gpio, gpio_to_irq(arizona->pdata.irq_gpio)); arizona->irq = gpio_to_irq(arizona->pdata.irq_gpio); } ret = gpio_request_one(arizona->pdata.irq_gpio, GPIOF_IN, "arizona IRQ"); if (ret != 0) { dev_err(arizona->dev, "Failed to request IRQ GPIO %d:: %d\n", arizona->pdata.irq_gpio, ret); arizona->pdata.irq_gpio = 0; } } ret = request_threaded_irq(arizona->irq, NULL, arizona_irq_thread, flags, "arizona", arizona); if (ret != 0) { dev_err(arizona->dev, "Failed to request primary IRQ %d: %d\n", arizona->irq, ret); goto err_main_irq; } return 0; err_main_irq: free_irq(arizona_map_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR), arizona); err_ctrlif: free_irq(arizona_map_irq(arizona, ARIZONA_IRQ_BOOT_DONE), arizona); err_boot_done: regmap_del_irq_chip(arizona->virq[1], arizona->irq_chip); err_aod: regmap_del_irq_chip(arizona->virq[0], arizona->aod_irq_chip); err_domain: err: return ret; }
static int max8907_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct max8907 *max8907; int ret; struct max8907_platform_data *pdata = dev_get_platdata(&i2c->dev); bool pm_off = false; if (pdata) pm_off = pdata->pm_off; else if (i2c->dev.of_node) pm_off = of_property_read_bool(i2c->dev.of_node, "maxim,system-power-controller"); max8907 = devm_kzalloc(&i2c->dev, sizeof(struct max8907), GFP_KERNEL); if (!max8907) { ret = -ENOMEM; goto err_alloc_drvdata; } max8907->dev = &i2c->dev; dev_set_drvdata(max8907->dev, max8907); max8907->i2c_gen = i2c; i2c_set_clientdata(i2c, max8907); max8907->regmap_gen = devm_regmap_init_i2c(i2c, &max8907_regmap_gen_config); if (IS_ERR(max8907->regmap_gen)) { ret = PTR_ERR(max8907->regmap_gen); dev_err(&i2c->dev, "gen regmap init failed: %d\n", ret); goto err_regmap_gen; } max8907->i2c_rtc = i2c_new_dummy(i2c->adapter, MAX8907_RTC_I2C_ADDR); if (!max8907->i2c_rtc) { ret = -ENOMEM; goto err_dummy_rtc; } i2c_set_clientdata(max8907->i2c_rtc, max8907); max8907->regmap_rtc = devm_regmap_init_i2c(max8907->i2c_rtc, &max8907_regmap_rtc_config); if (IS_ERR(max8907->regmap_rtc)) { ret = PTR_ERR(max8907->regmap_rtc); dev_err(&i2c->dev, "rtc regmap init failed: %d\n", ret); goto err_regmap_rtc; } irq_set_status_flags(max8907->i2c_gen->irq, IRQ_NOAUTOEN); ret = regmap_add_irq_chip(max8907->regmap_gen, max8907->i2c_gen->irq, IRQF_ONESHOT | IRQF_SHARED, -1, &max8907_chg_irq_chip, &max8907->irqc_chg); if (ret != 0) { dev_err(&i2c->dev, "failed to add chg irq chip: %d\n", ret); goto err_irqc_chg; } ret = regmap_add_irq_chip(max8907->regmap_gen, max8907->i2c_gen->irq, IRQF_ONESHOT | IRQF_SHARED, -1, &max8907_on_off_irq_chip, &max8907->irqc_on_off); if (ret != 0) { dev_err(&i2c->dev, "failed to add on off irq chip: %d\n", ret); goto err_irqc_on_off; } ret = regmap_add_irq_chip(max8907->regmap_rtc, max8907->i2c_gen->irq, IRQF_ONESHOT | IRQF_SHARED, -1, &max8907_rtc_irq_chip, &max8907->irqc_rtc); if (ret != 0) { dev_err(&i2c->dev, "failed to add rtc irq chip: %d\n", ret); goto err_irqc_rtc; } enable_irq(max8907->i2c_gen->irq); ret = mfd_add_devices(max8907->dev, -1, max8907_cells, ARRAY_SIZE(max8907_cells), NULL, 0, NULL); if (ret != 0) { dev_err(&i2c->dev, "failed to add MFD devices %d\n", ret); goto err_add_devices; } if (pm_off && !pm_power_off) { max8907_pm_off = max8907; pm_power_off = max8907_power_off; } return 0; err_add_devices: regmap_del_irq_chip(max8907->i2c_gen->irq, max8907->irqc_rtc); err_irqc_rtc: regmap_del_irq_chip(max8907->i2c_gen->irq, max8907->irqc_on_off); err_irqc_on_off: regmap_del_irq_chip(max8907->i2c_gen->irq, max8907->irqc_chg); err_irqc_chg: err_regmap_rtc: i2c_unregister_device(max8907->i2c_rtc); err_dummy_rtc: err_regmap_gen: err_alloc_drvdata: return ret; }
int wm8994_irq_init(struct wm8994 *wm8994) { int ret; unsigned long irqflags; struct wm8994_pdata *pdata = dev_get_platdata(wm8994->dev); if (!wm8994->irq) { dev_warn(wm8994->dev, "No interrupt specified, no interrupts\n"); wm8994->irq_base = 0; return 0; } /* select user or default irq flags */ irqflags = IRQF_TRIGGER_HIGH | IRQF_ONESHOT; if (pdata->irq_flags) irqflags = pdata->irq_flags; /* use a GPIO for edge triggered controllers */ if (irqflags & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) { if (gpio_to_irq(pdata->irq_gpio) != wm8994->irq) { dev_warn(wm8994->dev, "IRQ %d is not GPIO %d (%d)\n", wm8994->irq, pdata->irq_gpio, gpio_to_irq(pdata->irq_gpio)); wm8994->irq = gpio_to_irq(pdata->irq_gpio); } ret = devm_gpio_request_one(wm8994->dev, pdata->irq_gpio, GPIOF_IN, "WM8994 IRQ"); if (ret != 0) { dev_err(wm8994->dev, "Failed to get IRQ GPIO: %d\n", ret); return ret; } wm8994->edge_irq = irq_domain_add_linear(NULL, 1, &wm8994_edge_irq_ops, wm8994); ret = regmap_add_irq_chip(wm8994->regmap, irq_create_mapping(wm8994->edge_irq, 0), IRQF_ONESHOT, wm8994->irq_base, &wm8994_irq_chip, &wm8994->irq_data); if (ret != 0) { dev_err(wm8994->dev, "Failed to get IRQ: %d\n", ret); return ret; } ret = request_threaded_irq(wm8994->irq, NULL, wm8994_edge_irq, irqflags, "WM8994 edge", wm8994); } else { ret = regmap_add_irq_chip(wm8994->regmap, wm8994->irq, irqflags, wm8994->irq_base, &wm8994_irq_chip, &wm8994->irq_data); } if (ret != 0) { dev_err(wm8994->dev, "Failed to register IRQ chip: %d\n", ret); return ret; } /* Enable top level interrupt if it was masked */ wm8994_reg_write(wm8994, WM8994_INTERRUPT_CONTROL, 0); return 0; }
static int intel_soc_pmic_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *i2c_id) { struct device *dev = &i2c->dev; struct intel_soc_pmic_config *config; struct intel_soc_pmic *pmic; unsigned long long hrv; acpi_status status; int ret; /* * There are 2 different Crystal Cove PMICs a Bay Trail and Cherry * Trail version, use _HRV to differentiate between the 2. */ status = acpi_evaluate_integer(ACPI_HANDLE(dev), "_HRV", NULL, &hrv); if (ACPI_FAILURE(status)) { dev_err(dev, "Failed to get PMIC hardware revision\n"); return -ENODEV; } switch (hrv) { case BYT_CRC_HRV: config = &intel_soc_pmic_config_byt_crc; break; case CHT_CRC_HRV: config = &intel_soc_pmic_config_cht_crc; break; default: dev_warn(dev, "Unknown hardware rev %llu, assuming BYT\n", hrv); config = &intel_soc_pmic_config_byt_crc; } pmic = devm_kzalloc(dev, sizeof(*pmic), GFP_KERNEL); if (!pmic) return -ENOMEM; dev_set_drvdata(dev, pmic); pmic->regmap = devm_regmap_init_i2c(i2c, config->regmap_config); if (IS_ERR(pmic->regmap)) return PTR_ERR(pmic->regmap); pmic->irq = i2c->irq; ret = regmap_add_irq_chip(pmic->regmap, pmic->irq, config->irq_flags | IRQF_ONESHOT, 0, config->irq_chip, &pmic->irq_chip_data); if (ret) return ret; ret = enable_irq_wake(pmic->irq); if (ret) dev_warn(dev, "Can't enable IRQ as wake source: %d\n", ret); /* Add lookup table binding for Panel Control to the GPIO Chip */ gpiod_add_lookup_table(&panel_gpio_table); /* Add lookup table for crc-pwm */ pwm_add_table(crc_pwm_lookup, ARRAY_SIZE(crc_pwm_lookup)); ret = mfd_add_devices(dev, -1, config->cell_dev, config->n_cell_devs, NULL, 0, regmap_irq_get_domain(pmic->irq_chip_data)); if (ret) goto err_del_irq_chip; return 0; err_del_irq_chip: regmap_del_irq_chip(pmic->irq, pmic->irq_chip_data); return ret; }
static int hi655x_pmic_probe(struct platform_device *pdev) { int ret; struct hi655x_pmic *pmic; struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; void __iomem *base; pmic = devm_kzalloc(dev, sizeof(*pmic), GFP_KERNEL); if (!pmic) return -ENOMEM; pmic->dev = dev; pmic->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); base = devm_ioremap_resource(dev, pmic->res); if (IS_ERR(base)) return PTR_ERR(base); pmic->regmap = devm_regmap_init_mmio_clk(dev, NULL, base, &hi655x_regmap_config); regmap_read(pmic->regmap, HI655X_BUS_ADDR(HI655X_VER_REG), &pmic->ver); if ((pmic->ver < PMU_VER_START) || (pmic->ver > PMU_VER_END)) { dev_warn(dev, "PMU version %d unsupported\n", pmic->ver); return -EINVAL; } hi655x_local_irq_clear(pmic->regmap); pmic->gpio = of_get_named_gpio(np, "pmic-gpios", 0); if (!gpio_is_valid(pmic->gpio)) { dev_err(dev, "Failed to get the pmic-gpios\n"); return -ENODEV; } ret = devm_gpio_request_one(dev, pmic->gpio, GPIOF_IN, "hi655x_pmic_irq"); if (ret < 0) { dev_err(dev, "Failed to request gpio %d ret = %d\n", pmic->gpio, ret); return ret; } ret = regmap_add_irq_chip(pmic->regmap, gpio_to_irq(pmic->gpio), IRQF_TRIGGER_LOW | IRQF_NO_SUSPEND, 0, &hi655x_irq_chip, &pmic->irq_data); if (ret) { dev_err(dev, "Failed to obtain 'hi655x_pmic_irq' %d\n", ret); return ret; } platform_set_drvdata(pdev, pmic); ret = mfd_add_devices(dev, PLATFORM_DEVID_AUTO, hi655x_pmic_devs, ARRAY_SIZE(hi655x_pmic_devs), NULL, 0, regmap_irq_get_domain(pmic->irq_data)); if (ret) { dev_err(dev, "Failed to register device %d\n", ret); regmap_del_irq_chip(gpio_to_irq(pmic->gpio), pmic->irq_data); return ret; } return 0; }
static int twl6040_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct twl6040_platform_data *pdata = client->dev.platform_data; struct device_node *node = client->dev.of_node; struct twl6040 *twl6040; struct mfd_cell *cell = NULL; int irq, ret, children = 0; if (!pdata && !node) { dev_err(&client->dev, "Platform data is missing\n"); return -EINVAL; } /* In order to operate correctly we need valid interrupt config */ if (!client->irq) { dev_err(&client->dev, "Invalid IRQ configuration\n"); return -EINVAL; } twl6040 = devm_kzalloc(&client->dev, sizeof(struct twl6040), GFP_KERNEL); if (!twl6040) { ret = -ENOMEM; goto err; } twl6040->regmap = devm_regmap_init_i2c(client, &twl6040_regmap_config); if (IS_ERR(twl6040->regmap)) { ret = PTR_ERR(twl6040->regmap); goto err; } i2c_set_clientdata(client, twl6040); twl6040->supplies[0].supply = "vio"; twl6040->supplies[1].supply = "v2v1"; ret = devm_regulator_bulk_get(&client->dev, TWL6040_NUM_SUPPLIES, twl6040->supplies); if (ret != 0) { dev_err(&client->dev, "Failed to get supplies: %d\n", ret); goto regulator_get_err; } ret = regulator_bulk_enable(TWL6040_NUM_SUPPLIES, twl6040->supplies); if (ret != 0) { dev_err(&client->dev, "Failed to enable supplies: %d\n", ret); goto regulator_get_err; } twl6040->dev = &client->dev; twl6040->irq = client->irq; mutex_init(&twl6040->mutex); init_completion(&twl6040->ready); twl6040->rev = twl6040_reg_read(twl6040, TWL6040_REG_ASICREV); /* ERRATA: Automatic power-up is not possible in ES1.0 */ if (twl6040_get_revid(twl6040) > TWL6040_REV_ES1_0) { if (pdata) twl6040->audpwron = pdata->audpwron_gpio; else twl6040->audpwron = of_get_named_gpio(node, "ti,audpwron-gpio", 0); } else twl6040->audpwron = -EINVAL; if (gpio_is_valid(twl6040->audpwron)) { ret = devm_gpio_request_one(&client->dev, twl6040->audpwron, GPIOF_OUT_INIT_LOW, "audpwron"); if (ret) goto gpio_err; } ret = regmap_add_irq_chip(twl6040->regmap, twl6040->irq, IRQF_ONESHOT, 0, &twl6040_irq_chip, &twl6040->irq_data); if (ret < 0) goto gpio_err; twl6040->irq_ready = regmap_irq_get_virq(twl6040->irq_data, TWL6040_IRQ_READY); twl6040->irq_th = regmap_irq_get_virq(twl6040->irq_data, TWL6040_IRQ_TH); ret = devm_request_threaded_irq(twl6040->dev, twl6040->irq_ready, NULL, twl6040_readyint_handler, IRQF_ONESHOT, "twl6040_irq_ready", twl6040); if (ret) { dev_err(twl6040->dev, "READY IRQ request failed: %d\n", ret); goto readyirq_err; } ret = devm_request_threaded_irq(twl6040->dev, twl6040->irq_th, NULL, twl6040_thint_handler, IRQF_ONESHOT, "twl6040_irq_th", twl6040); if (ret) { dev_err(twl6040->dev, "Thermal IRQ request failed: %d\n", ret); goto thirq_err; } /* dual-access registers controlled by I2C only */ twl6040_set_bits(twl6040, TWL6040_REG_ACCCTL, TWL6040_I2CSEL); /* * The main functionality of twl6040 to provide audio on OMAP4+ systems. * We can add the ASoC codec child whenever this driver has been loaded. * The ASoC codec can work without pdata, pass the platform_data only if * it has been provided. */ irq = regmap_irq_get_virq(twl6040->irq_data, TWL6040_IRQ_PLUG); cell = &twl6040->cells[children]; cell->name = "twl6040-codec"; twl6040_codec_rsrc[0].start = irq; twl6040_codec_rsrc[0].end = irq; cell->resources = twl6040_codec_rsrc; cell->num_resources = ARRAY_SIZE(twl6040_codec_rsrc); if (pdata && pdata->codec) { cell->platform_data = pdata->codec; cell->pdata_size = sizeof(*pdata->codec); } children++; if (twl6040_has_vibra(pdata, node)) { irq = regmap_irq_get_virq(twl6040->irq_data, TWL6040_IRQ_VIB); cell = &twl6040->cells[children]; cell->name = "twl6040-vibra"; twl6040_vibra_rsrc[0].start = irq; twl6040_vibra_rsrc[0].end = irq; cell->resources = twl6040_vibra_rsrc; cell->num_resources = ARRAY_SIZE(twl6040_vibra_rsrc); if (pdata && pdata->vibra) { cell->platform_data = pdata->vibra; cell->pdata_size = sizeof(*pdata->vibra); } children++; } /* * Enable the GPO driver in the following cases: * DT booted kernel or legacy boot with valid gpo platform_data */ if (!pdata || (pdata && pdata->gpo)) { cell = &twl6040->cells[children]; cell->name = "twl6040-gpo"; if (pdata) { cell->platform_data = pdata->gpo; cell->pdata_size = sizeof(*pdata->gpo); } children++; } ret = mfd_add_devices(&client->dev, -1, twl6040->cells, children, NULL, 0, NULL); if (ret) goto mfd_err; return 0; mfd_err: devm_free_irq(&client->dev, twl6040->irq_th, twl6040); thirq_err: devm_free_irq(&client->dev, twl6040->irq_ready, twl6040); readyirq_err: regmap_del_irq_chip(twl6040->irq, twl6040->irq_data); gpio_err: regulator_bulk_disable(TWL6040_NUM_SUPPLIES, twl6040->supplies); regulator_get_err: i2c_set_clientdata(client, NULL); err: return ret; }
static int max77843_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct max77843 *max77843; unsigned int reg_data; int ret; max77843 = devm_kzalloc(&i2c->dev, sizeof(*max77843), GFP_KERNEL); if (!max77843) return -ENOMEM; i2c_set_clientdata(i2c, max77843); max77843->dev = &i2c->dev; max77843->i2c = i2c; max77843->irq = i2c->irq; max77843->regmap = devm_regmap_init_i2c(i2c, &max77843_regmap_config); if (IS_ERR(max77843->regmap)) { dev_err(&i2c->dev, "Failed to allocate topsys register map\n"); return PTR_ERR(max77843->regmap); } ret = regmap_add_irq_chip(max77843->regmap, max77843->irq, IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED, 0, &max77843_irq_chip, &max77843->irq_data); if (ret) { dev_err(&i2c->dev, "Failed to add TOPSYS IRQ chip\n"); return ret; } ret = regmap_read(max77843->regmap, MAX77843_SYS_REG_PMICID, ®_data); if (ret < 0) { dev_err(&i2c->dev, "Failed to read PMIC ID\n"); goto err_pmic_id; } dev_info(&i2c->dev, "device ID: 0x%x\n", reg_data); ret = max77843_chg_init(max77843); if (ret) { dev_err(&i2c->dev, "Failed to init Charger\n"); goto err_pmic_id; } ret = regmap_update_bits(max77843->regmap, MAX77843_SYS_REG_INTSRCMASK, MAX77843_INTSRC_MASK_MASK, (unsigned int)~MAX77843_INTSRC_MASK_MASK); if (ret < 0) { dev_err(&i2c->dev, "Failed to unmask interrupt source\n"); goto err_pmic_id; } ret = mfd_add_devices(max77843->dev, -1, max77843_devs, ARRAY_SIZE(max77843_devs), NULL, 0, NULL); if (ret < 0) { dev_err(&i2c->dev, "Failed to add mfd device\n"); goto err_pmic_id; } device_init_wakeup(max77843->dev, true); return 0; err_pmic_id: regmap_del_irq_chip(max77843->irq, max77843->irq_data); return ret; }
static int palmas_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct palmas *palmas; struct palmas_platform_data *pdata; struct device_node *node = i2c->dev.of_node; int ret = 0, i; unsigned int reg, addr, *features; int slave; const struct of_device_id *match; pdata = dev_get_platdata(&i2c->dev); if (node && !pdata) { pdata = devm_kzalloc(&i2c->dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) return -ENOMEM; palmas_dt_to_pdata(i2c, pdata); } if (!pdata) return -EINVAL; palmas = devm_kzalloc(&i2c->dev, sizeof(struct palmas), GFP_KERNEL); if (palmas == NULL) return -ENOMEM; i2c_set_clientdata(i2c, palmas); palmas->dev = &i2c->dev; palmas->irq = i2c->irq; match = of_match_device(of_match_ptr(of_palmas_match_tbl), &i2c->dev); if (!match) return -ENODATA; features = (unsigned int *)match->data; palmas->features = *features; for (i = 0; i < PALMAS_NUM_CLIENTS; i++) { if (i == 0) palmas->i2c_clients[i] = i2c; else { palmas->i2c_clients[i] = i2c_new_dummy(i2c->adapter, i2c->addr + i); if (!palmas->i2c_clients[i]) { dev_err(palmas->dev, "can't attach client %d\n", i); ret = -ENOMEM; goto err; } palmas->i2c_clients[i]->dev.of_node = of_node_get(node); } palmas->regmap[i] = devm_regmap_init_i2c(palmas->i2c_clients[i], &palmas_regmap_config[i]); if (IS_ERR(palmas->regmap[i])) { ret = PTR_ERR(palmas->regmap[i]); dev_err(palmas->dev, "Failed to allocate regmap %d, err: %d\n", i, ret); goto err; } } if (!palmas->irq) { dev_warn(palmas->dev, "IRQ missing: skipping irq request\n"); goto no_irq; } /* Change interrupt line output polarity */ if (pdata->irq_flags & IRQ_TYPE_LEVEL_HIGH) reg = PALMAS_POLARITY_CTRL_INT_POLARITY; else reg = 0; ret = palmas_update_bits(palmas, PALMAS_PU_PD_OD_BASE, PALMAS_POLARITY_CTRL, PALMAS_POLARITY_CTRL_INT_POLARITY, reg); if (ret < 0) { dev_err(palmas->dev, "POLARITY_CTRL updat failed: %d\n", ret); goto err; } /* Change IRQ into clear on read mode for efficiency */ slave = PALMAS_BASE_TO_SLAVE(PALMAS_INTERRUPT_BASE); addr = PALMAS_BASE_TO_REG(PALMAS_INTERRUPT_BASE, PALMAS_INT_CTRL); reg = PALMAS_INT_CTRL_INT_CLEAR; regmap_write(palmas->regmap[slave], addr, reg); ret = regmap_add_irq_chip(palmas->regmap[slave], palmas->irq, IRQF_ONESHOT | pdata->irq_flags, 0, &palmas_irq_chip, &palmas->irq_data); if (ret < 0) goto err; no_irq: slave = PALMAS_BASE_TO_SLAVE(PALMAS_PU_PD_OD_BASE); addr = PALMAS_BASE_TO_REG(PALMAS_PU_PD_OD_BASE, PALMAS_PRIMARY_SECONDARY_PAD1); if (pdata->mux_from_pdata) { reg = pdata->pad1; ret = regmap_write(palmas->regmap[slave], addr, reg); if (ret) goto err_irq; } else { ret = regmap_read(palmas->regmap[slave], addr, ®); if (ret) goto err_irq; } if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_0)) palmas->gpio_muxed |= PALMAS_GPIO_0_MUXED; if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_1_MASK)) palmas->gpio_muxed |= PALMAS_GPIO_1_MUXED; else if ((reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_1_MASK) == (2 << PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_1_SHIFT)) palmas->led_muxed |= PALMAS_LED1_MUXED; else if ((reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_1_MASK) == (3 << PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_1_SHIFT)) palmas->pwm_muxed |= PALMAS_PWM1_MUXED; if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_2_MASK)) palmas->gpio_muxed |= PALMAS_GPIO_2_MUXED; else if ((reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_2_MASK) == (2 << PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_2_SHIFT)) palmas->led_muxed |= PALMAS_LED2_MUXED; else if ((reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_2_MASK) == (3 << PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_2_SHIFT)) palmas->pwm_muxed |= PALMAS_PWM2_MUXED; if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_3)) palmas->gpio_muxed |= PALMAS_GPIO_3_MUXED; addr = PALMAS_BASE_TO_REG(PALMAS_PU_PD_OD_BASE, PALMAS_PRIMARY_SECONDARY_PAD2); if (pdata->mux_from_pdata) { reg = pdata->pad2; ret = regmap_write(palmas->regmap[slave], addr, reg); if (ret) goto err_irq; } else { ret = regmap_read(palmas->regmap[slave], addr, ®); if (ret) goto err_irq; } if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_4)) palmas->gpio_muxed |= PALMAS_GPIO_4_MUXED; if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_5_MASK)) palmas->gpio_muxed |= PALMAS_GPIO_5_MUXED; if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_6)) palmas->gpio_muxed |= PALMAS_GPIO_6_MUXED; if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_7_MASK)) palmas->gpio_muxed |= PALMAS_GPIO_7_MUXED; dev_info(palmas->dev, "Muxing GPIO %x, PWM %x, LED %x\n", palmas->gpio_muxed, palmas->pwm_muxed, palmas->led_muxed); reg = pdata->power_ctrl; slave = PALMAS_BASE_TO_SLAVE(PALMAS_PMU_CONTROL_BASE); addr = PALMAS_BASE_TO_REG(PALMAS_PMU_CONTROL_BASE, PALMAS_POWER_CTRL); ret = regmap_write(palmas->regmap[slave], addr, reg); if (ret) goto err_irq; /* * If we are probing with DT do this the DT way and return here * otherwise continue and add devices using mfd helpers. */ if (node) { ret = of_platform_populate(node, NULL, NULL, &i2c->dev); if (ret < 0) goto err_irq; else return ret; } return ret; err_irq: regmap_del_irq_chip(palmas->irq, palmas->irq_data); err: return ret; }
static int max14577_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct max14577 *max14577; struct max14577_platform_data *pdata = dev_get_platdata(&i2c->dev); struct device_node *np = i2c->dev.of_node; u8 reg_data; int ret = 0; if (np) { pdata = devm_kzalloc(&i2c->dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) return -ENOMEM; i2c->dev.platform_data = pdata; } if (!pdata) { dev_err(&i2c->dev, "No platform data found.\n"); return -EINVAL; } max14577 = devm_kzalloc(&i2c->dev, sizeof(*max14577), GFP_KERNEL); if (!max14577) return -ENOMEM; i2c_set_clientdata(i2c, max14577); max14577->dev = &i2c->dev; max14577->i2c = i2c; max14577->irq = i2c->irq; max14577->regmap = devm_regmap_init_i2c(i2c, &max14577_regmap_config); if (IS_ERR(max14577->regmap)) { ret = PTR_ERR(max14577->regmap); dev_err(max14577->dev, "Failed to allocate register map: %d\n", ret); return ret; } ret = max14577_read_reg(max14577->regmap, MAX14577_REG_DEVICEID, ®_data); if (ret) { dev_err(max14577->dev, "Device not found on this channel: %d\n", ret); return ret; } max14577->vendor_id = ((reg_data & DEVID_VENDORID_MASK) >> DEVID_VENDORID_SHIFT); max14577->device_id = ((reg_data & DEVID_DEVICEID_MASK) >> DEVID_DEVICEID_SHIFT); dev_info(max14577->dev, "Device ID: 0x%x, vendor: 0x%x\n", max14577->device_id, max14577->vendor_id); ret = regmap_add_irq_chip(max14577->regmap, max14577->irq, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 0, &max14577_irq_chip, &max14577->irq_data); if (ret != 0) { dev_err(&i2c->dev, "Failed to request IRQ %d: %d\n", max14577->irq, ret); return ret; } ret = mfd_add_devices(max14577->dev, -1, max14577_devs, ARRAY_SIZE(max14577_devs), NULL, 0, regmap_irq_get_domain(max14577->irq_data)); if (ret < 0) goto err_mfd; device_init_wakeup(max14577->dev, 1); return 0; err_mfd: regmap_del_irq_chip(max14577->irq, max14577->irq_data); return ret; }
int arizona_irq_init(struct arizona *arizona) { int flags = IRQF_ONESHOT; int ret, i; struct regmap_irq_chip *aod, *irq; bool ctrlif_error = true; int irq_base; switch (arizona->type) { #ifdef CONFIG_MFD_WM5102 case WM5102: aod = &wm5102_aod; irq = &wm5102_irq; switch (arizona->rev) { case 0: ctrlif_error = false; break; default: break; } break; #endif #ifdef CONFIG_MFD_WM5110 case WM5110: aod = &wm5110_aod; irq = &wm5110_irq; switch (arizona->rev) { case 0: ctrlif_error = false; break; default: break; } break; #endif default: BUG_ON("Unknown Arizona class device" == NULL); return -EINVAL; } if (arizona->pdata.irq_active_high) { ret = regmap_update_bits(arizona->regmap, ARIZONA_IRQ_CTRL_1, ARIZONA_IRQ_POL, 0); if (ret != 0) { dev_err(arizona->dev, "Couldn't set IRQ polarity: %d\n", ret); goto err; } flags |= IRQF_TRIGGER_HIGH; } else { flags |= IRQF_TRIGGER_LOW; } /* set virtual IRQs */ if (arizona->pdata.irq_base > 0) { arizona->virq[0] = arizona->pdata.irq_base; arizona->virq[1] = arizona->pdata.irq_base + 1; } else { dev_err(arizona->dev, "No irq_base specified\n"); return -EINVAL; } ret = irq_alloc_descs(arizona->pdata.irq_base, 0, ARRAY_SIZE(arizona->virq), 0); if (ret < 0) { dev_err(arizona->dev, "Failed to allocate IRQs: %d\n", ret); return ret; } for (i = 0; i < ARRAY_SIZE(arizona->virq); i++) { irq_set_chip_data(arizona->virq[i], arizona); irq_set_chip_and_handler(arizona->virq[i], &arizona_irq_chip, handle_edge_irq); irq_set_nested_thread(arizona->virq[i], 1); /* ARM needs us to explicitly flag the IRQ as valid and * will set them noprobe when we do so. */ #ifdef CONFIG_ARM set_irq_flags(arizona->virq[i], IRQF_VALID); #else irq_set_noprobe(arizona->virq[i]); #endif } irq_base = arizona->pdata.irq_base + 2; ret = regmap_add_irq_chip(arizona->regmap, arizona->virq[0], IRQF_ONESHOT, irq_base, aod, &arizona->aod_irq_chip); if (ret != 0) { dev_err(arizona->dev, "Failed to add AOD IRQs: %d\n", ret); goto err_domain; } irq_base = arizona->pdata.irq_base + 2 + ARIZONA_NUM_IRQ; ret = regmap_add_irq_chip(arizona->regmap, arizona->virq[1], IRQF_ONESHOT, irq_base, irq, &arizona->irq_chip); if (ret != 0) { dev_err(arizona->dev, "Failed to add IRQs: %d\n", ret); goto err_aod; } /* Make sure the boot done IRQ is unmasked for resumes */ i = arizona_map_irq(arizona, ARIZONA_IRQ_BOOT_DONE); ret = request_threaded_irq(i, NULL, arizona_boot_done, IRQF_ONESHOT, "Boot done", arizona); if (ret != 0) { dev_err(arizona->dev, "Failed to request boot done %d: %d\n", arizona->irq, ret); goto err_boot_done; } /* Handle control interface errors in the core */ if (ctrlif_error) { i = arizona_map_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR); ret = request_threaded_irq(i, NULL, arizona_ctrlif_err, IRQF_ONESHOT, "Control interface error", arizona); if (ret != 0) { dev_err(arizona->dev, "Failed to request CTRLIF_ERR %d: %d\n", arizona->irq, ret); goto err_ctrlif; } } ret = request_threaded_irq(arizona->irq, NULL, arizona_irq_thread, flags, "arizona", arizona); if (ret != 0) { dev_err(arizona->dev, "Failed to request IRQ %d: %d\n", arizona->irq, ret); goto err_main_irq; } return 0; err_main_irq: free_irq(arizona_map_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR), arizona); err_ctrlif: free_irq(arizona_map_irq(arizona, ARIZONA_IRQ_BOOT_DONE), arizona); err_boot_done: regmap_del_irq_chip(arizona->virq[1], arizona->irq_chip); err_aod: regmap_del_irq_chip(arizona->virq[0], arizona->aod_irq_chip); err_domain: err: return ret; }
static int as3722_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct as3722 *as3722; unsigned long irq_flags; int ret; u8 val = 0; as3722 = devm_kzalloc(&i2c->dev, sizeof(struct as3722), GFP_KERNEL); if (!as3722) return -ENOMEM; as3722->dev = &i2c->dev; as3722->chip_irq = i2c->irq; i2c_set_clientdata(i2c, as3722); ret = as3722_i2c_non_of_probe(i2c, as3722); if (ret < 0) { ret = as3722_i2c_of_probe(i2c, as3722); if (ret < 0) return ret; } as3722->regmap = devm_regmap_init_i2c(i2c, &as3722_regmap_config); if (IS_ERR(as3722->regmap)) { ret = PTR_ERR(as3722->regmap); dev_err(&i2c->dev, "regmap init failed: %d\n", ret); return ret; } ret = as3722_check_device_id(as3722); if (ret < 0) return ret; irq_flags = as3722->irq_flags | IRQF_ONESHOT; ret = regmap_add_irq_chip(as3722->regmap, as3722->chip_irq, irq_flags, as3722->irq_base, &as3722_irq_chip, &as3722->irq_data); if (ret < 0) { dev_err(as3722->dev, "Failed to add regmap irq: %d\n", ret); return ret; } ret = as3722_configure_pullups(as3722); if (ret < 0) goto scrub; if (as3722->en_ac_ok_pwr_on) val = AS3722_CTRL_SEQ1_AC_OK_PWR_ON; ret = as3722_update_bits(as3722, AS3722_CTRL_SEQU1_REG, AS3722_CTRL_SEQ1_AC_OK_PWR_ON, val); if (ret < 0) { dev_err(as3722->dev, "CTRL_SEQ1 update failed: %d\n", ret); goto scrub; } ret = mfd_add_devices(&i2c->dev, -1, as3722_devs, ARRAY_SIZE(as3722_devs), NULL, 0, regmap_irq_get_domain(as3722->irq_data)); if (ret) { dev_err(as3722->dev, "Failed to add MFD devices: %d\n", ret); goto scrub; } dev_dbg(as3722->dev, "AS3722 core driver initialized successfully\n"); return 0; scrub: regmap_del_irq_chip(as3722->chip_irq, as3722->irq_data); return ret; }
static int max77693_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct max77693_dev *max77693; unsigned int reg_data; int ret = 0; max77693 = devm_kzalloc(&i2c->dev, sizeof(struct max77693_dev), GFP_KERNEL); if (max77693 == NULL) return -ENOMEM; i2c_set_clientdata(i2c, max77693); max77693->dev = &i2c->dev; max77693->i2c = i2c; max77693->irq = i2c->irq; max77693->type = id->driver_data; max77693->regmap = devm_regmap_init_i2c(i2c, &max77693_regmap_config); if (IS_ERR(max77693->regmap)) { ret = PTR_ERR(max77693->regmap); dev_err(max77693->dev, "failed to allocate register map: %d\n", ret); return ret; } ret = regmap_read(max77693->regmap, MAX77693_PMIC_REG_PMIC_ID2, ®_data); if (ret < 0) { dev_err(max77693->dev, "device not found on this channel\n"); return ret; } else dev_info(max77693->dev, "device ID: 0x%x\n", reg_data); max77693->muic = i2c_new_dummy(i2c->adapter, I2C_ADDR_MUIC); if (!max77693->muic) { dev_err(max77693->dev, "Failed to allocate I2C device for MUIC\n"); return -ENODEV; } i2c_set_clientdata(max77693->muic, max77693); max77693->haptic = i2c_new_dummy(i2c->adapter, I2C_ADDR_HAPTIC); if (!max77693->haptic) { dev_err(max77693->dev, "Failed to allocate I2C device for Haptic\n"); ret = -ENODEV; goto err_i2c_haptic; } i2c_set_clientdata(max77693->haptic, max77693); max77693->regmap_haptic = devm_regmap_init_i2c(max77693->haptic, &max77693_regmap_haptic_config); if (IS_ERR(max77693->regmap_haptic)) { ret = PTR_ERR(max77693->regmap_haptic); dev_err(max77693->dev, "failed to initialize haptic register map: %d\n", ret); goto err_regmap; } /* * Initialize register map for MUIC device because use regmap-muic * instance of MUIC device when irq of max77693 is initialized * before call max77693-muic probe() function. */ max77693->regmap_muic = devm_regmap_init_i2c(max77693->muic, &max77693_regmap_muic_config); if (IS_ERR(max77693->regmap_muic)) { ret = PTR_ERR(max77693->regmap_muic); dev_err(max77693->dev, "failed to allocate register map: %d\n", ret); goto err_regmap; } ret = regmap_add_irq_chip(max77693->regmap, max77693->irq, IRQF_ONESHOT | IRQF_SHARED | IRQF_TRIGGER_FALLING, 0, &max77693_led_irq_chip, &max77693->irq_data_led); if (ret) { dev_err(max77693->dev, "failed to add irq chip: %d\n", ret); goto err_regmap; } ret = regmap_add_irq_chip(max77693->regmap, max77693->irq, IRQF_ONESHOT | IRQF_SHARED | IRQF_TRIGGER_FALLING, 0, &max77693_topsys_irq_chip, &max77693->irq_data_topsys); if (ret) { dev_err(max77693->dev, "failed to add irq chip: %d\n", ret); goto err_irq_topsys; } ret = regmap_add_irq_chip(max77693->regmap, max77693->irq, IRQF_ONESHOT | IRQF_SHARED | IRQF_TRIGGER_FALLING, 0, &max77693_charger_irq_chip, &max77693->irq_data_charger); if (ret) { dev_err(max77693->dev, "failed to add irq chip: %d\n", ret); goto err_irq_charger; } ret = regmap_add_irq_chip(max77693->regmap_muic, max77693->irq, IRQF_ONESHOT | IRQF_SHARED | IRQF_TRIGGER_FALLING, 0, &max77693_muic_irq_chip,
static int da9150_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct da9150 *da9150; struct da9150_pdata *pdata = dev_get_platdata(&client->dev); int qif_addr; int ret; da9150 = devm_kzalloc(&client->dev, sizeof(*da9150), GFP_KERNEL); if (!da9150) return -ENOMEM; da9150->dev = &client->dev; da9150->irq = client->irq; i2c_set_clientdata(client, da9150); da9150->regmap = devm_regmap_init_i2c(client, &da9150_regmap_config); if (IS_ERR(da9150->regmap)) { ret = PTR_ERR(da9150->regmap); dev_err(da9150->dev, "Failed to allocate register map: %d\n", ret); return ret; } /* Setup secondary I2C interface for QIF access */ qif_addr = da9150_reg_read(da9150, DA9150_CORE2WIRE_CTRL_A); qif_addr = (qif_addr & DA9150_CORE_BASE_ADDR_MASK) >> 1; qif_addr |= DA9150_QIF_I2C_ADDR_LSB; da9150->core_qif = i2c_new_dummy(client->adapter, qif_addr); if (!da9150->core_qif) { dev_err(da9150->dev, "Failed to attach QIF client\n"); return -ENODEV; } i2c_set_clientdata(da9150->core_qif, da9150); if (pdata) { da9150->irq_base = pdata->irq_base; da9150_devs[DA9150_FG_IDX].platform_data = pdata->fg_pdata; da9150_devs[DA9150_FG_IDX].pdata_size = sizeof(struct da9150_fg_pdata); } else { da9150->irq_base = -1; } ret = regmap_add_irq_chip(da9150->regmap, da9150->irq, IRQF_TRIGGER_LOW | IRQF_ONESHOT, da9150->irq_base, &da9150_regmap_irq_chip, &da9150->regmap_irq_data); if (ret) { dev_err(da9150->dev, "Failed to add regmap irq chip: %d\n", ret); goto regmap_irq_fail; } da9150->irq_base = regmap_irq_chip_get_base(da9150->regmap_irq_data); enable_irq_wake(da9150->irq); ret = mfd_add_devices(da9150->dev, -1, da9150_devs, ARRAY_SIZE(da9150_devs), NULL, da9150->irq_base, NULL); if (ret) { dev_err(da9150->dev, "Failed to add child devices: %d\n", ret); goto mfd_fail; } return 0; mfd_fail: regmap_del_irq_chip(da9150->irq, da9150->regmap_irq_data); regmap_irq_fail: i2c_unregister_device(da9150->core_qif); return ret; }
static int twl6040_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct device_node *node = client->dev.of_node; struct twl6040 *twl6040; struct mfd_cell *cell = NULL; int irq, ret, children = 0; if (!node) { dev_err(&client->dev, "of node is missing\n"); return -EINVAL; } /* In order to operate correctly we need valid interrupt config */ if (!client->irq) { dev_err(&client->dev, "Invalid IRQ configuration\n"); return -EINVAL; } twl6040 = devm_kzalloc(&client->dev, sizeof(struct twl6040), GFP_KERNEL); if (!twl6040) return -ENOMEM; twl6040->regmap = devm_regmap_init_i2c(client, &twl6040_regmap_config); if (IS_ERR(twl6040->regmap)) return PTR_ERR(twl6040->regmap); i2c_set_clientdata(client, twl6040); twl6040->clk32k = devm_clk_get(&client->dev, "clk32k"); if (IS_ERR(twl6040->clk32k)) { if (PTR_ERR(twl6040->clk32k) == -EPROBE_DEFER) return -EPROBE_DEFER; dev_dbg(&client->dev, "clk32k is not handled\n"); twl6040->clk32k = NULL; } twl6040->mclk = devm_clk_get(&client->dev, "mclk"); if (IS_ERR(twl6040->mclk)) { if (PTR_ERR(twl6040->mclk) == -EPROBE_DEFER) return -EPROBE_DEFER; dev_dbg(&client->dev, "mclk is not handled\n"); twl6040->mclk = NULL; } twl6040->supplies[0].supply = "vio"; twl6040->supplies[1].supply = "v2v1"; ret = devm_regulator_bulk_get(&client->dev, TWL6040_NUM_SUPPLIES, twl6040->supplies); if (ret != 0) { dev_err(&client->dev, "Failed to get supplies: %d\n", ret); return ret; } ret = regulator_bulk_enable(TWL6040_NUM_SUPPLIES, twl6040->supplies); if (ret != 0) { dev_err(&client->dev, "Failed to enable supplies: %d\n", ret); return ret; } twl6040->dev = &client->dev; twl6040->irq = client->irq; mutex_init(&twl6040->mutex); init_completion(&twl6040->ready); regmap_register_patch(twl6040->regmap, twl6040_patch, ARRAY_SIZE(twl6040_patch)); twl6040->rev = twl6040_reg_read(twl6040, TWL6040_REG_ASICREV); if (twl6040->rev < 0) { dev_err(&client->dev, "Failed to read revision register: %d\n", twl6040->rev); ret = twl6040->rev; goto gpio_err; } /* ERRATA: Automatic power-up is not possible in ES1.0 */ if (twl6040_get_revid(twl6040) > TWL6040_REV_ES1_0) twl6040->audpwron = of_get_named_gpio(node, "ti,audpwron-gpio", 0); else twl6040->audpwron = -EINVAL; if (gpio_is_valid(twl6040->audpwron)) { ret = devm_gpio_request_one(&client->dev, twl6040->audpwron, GPIOF_OUT_INIT_LOW, "audpwron"); if (ret) goto gpio_err; /* Clear any pending interrupt */ twl6040_reg_read(twl6040, TWL6040_REG_INTID); } ret = regmap_add_irq_chip(twl6040->regmap, twl6040->irq, IRQF_ONESHOT, 0, &twl6040_irq_chip, &twl6040->irq_data); if (ret < 0) goto gpio_err; twl6040->irq_ready = regmap_irq_get_virq(twl6040->irq_data, TWL6040_IRQ_READY); twl6040->irq_th = regmap_irq_get_virq(twl6040->irq_data, TWL6040_IRQ_TH); ret = devm_request_threaded_irq(twl6040->dev, twl6040->irq_ready, NULL, twl6040_readyint_handler, IRQF_ONESHOT, "twl6040_irq_ready", twl6040); if (ret) { dev_err(twl6040->dev, "READY IRQ request failed: %d\n", ret); goto readyirq_err; } ret = devm_request_threaded_irq(twl6040->dev, twl6040->irq_th, NULL, twl6040_thint_handler, IRQF_ONESHOT, "twl6040_irq_th", twl6040); if (ret) { dev_err(twl6040->dev, "Thermal IRQ request failed: %d\n", ret); goto readyirq_err; } /* * The main functionality of twl6040 to provide audio on OMAP4+ systems. * We can add the ASoC codec child whenever this driver has been loaded. */ irq = regmap_irq_get_virq(twl6040->irq_data, TWL6040_IRQ_PLUG); cell = &twl6040->cells[children]; cell->name = "twl6040-codec"; twl6040_codec_rsrc[0].start = irq; twl6040_codec_rsrc[0].end = irq; cell->resources = twl6040_codec_rsrc; cell->num_resources = ARRAY_SIZE(twl6040_codec_rsrc); children++; /* Vibra input driver support */ if (twl6040_has_vibra(node)) { irq = regmap_irq_get_virq(twl6040->irq_data, TWL6040_IRQ_VIB); cell = &twl6040->cells[children]; cell->name = "twl6040-vibra"; twl6040_vibra_rsrc[0].start = irq; twl6040_vibra_rsrc[0].end = irq; cell->resources = twl6040_vibra_rsrc; cell->num_resources = ARRAY_SIZE(twl6040_vibra_rsrc); children++; } /* GPO support */ cell = &twl6040->cells[children]; cell->name = "twl6040-gpo"; children++; /* PDM clock support */ cell = &twl6040->cells[children]; cell->name = "twl6040-pdmclk"; children++; /* The chip is powered down so mark regmap to cache only and dirty */ regcache_cache_only(twl6040->regmap, true); regcache_mark_dirty(twl6040->regmap); ret = mfd_add_devices(&client->dev, -1, twl6040->cells, children, NULL, 0, NULL); if (ret) goto readyirq_err; return 0; readyirq_err: regmap_del_irq_chip(twl6040->irq, twl6040->irq_data); gpio_err: regulator_bulk_disable(TWL6040_NUM_SUPPLIES, twl6040->supplies); return ret; }
int arizona_irq_init(struct arizona *arizona) { int flags = IRQF_ONESHOT; int ret, i; const struct regmap_irq_chip *aod, *irq; struct irq_data *irq_data; arizona->ctrlif_error = true; switch (arizona->type) { #ifdef CONFIG_MFD_WM5102 case WM5102: aod = &wm5102_aod; irq = &wm5102_irq; arizona->ctrlif_error = false; break; #endif #ifdef CONFIG_MFD_WM5110 case WM5110: case WM8280: aod = &wm5110_aod; switch (arizona->rev) { case 0 ... 2: irq = &wm5110_irq; break; default: irq = &wm5110_revd_irq; break; } arizona->ctrlif_error = false; break; #endif #ifdef CONFIG_MFD_WM8997 case WM8997: aod = &wm8997_aod; irq = &wm8997_irq; arizona->ctrlif_error = false; break; #endif #ifdef CONFIG_MFD_WM8998 case WM8998: case WM1814: aod = &wm8998_aod; irq = &wm8998_irq; arizona->ctrlif_error = false; break; #endif default: BUG_ON("Unknown Arizona class device" == NULL); return -EINVAL; } /* Disable all wake sources by default */ regmap_write(arizona->regmap, ARIZONA_WAKE_CONTROL, 0); /* Read the flags from the interrupt controller if not specified */ if (!arizona->pdata.irq_flags) { irq_data = irq_get_irq_data(arizona->irq); if (!irq_data) { dev_err(arizona->dev, "Invalid IRQ: %d\n", arizona->irq); return -EINVAL; } arizona->pdata.irq_flags = irqd_get_trigger_type(irq_data); switch (arizona->pdata.irq_flags) { case IRQF_TRIGGER_LOW: case IRQF_TRIGGER_HIGH: case IRQF_TRIGGER_RISING: case IRQF_TRIGGER_FALLING: break; case IRQ_TYPE_NONE: default: /* Device default */ arizona->pdata.irq_flags = IRQF_TRIGGER_LOW; break; } } if (arizona->pdata.irq_flags & (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_RISING)) { ret = regmap_update_bits(arizona->regmap, ARIZONA_IRQ_CTRL_1, ARIZONA_IRQ_POL, 0); if (ret != 0) { dev_err(arizona->dev, "Couldn't set IRQ polarity: %d\n", ret); goto err; } } flags |= arizona->pdata.irq_flags; /* Allocate a virtual IRQ domain to distribute to the regmap domains */ arizona->virq = irq_domain_add_linear(NULL, 2, &arizona_domain_ops, arizona); if (!arizona->virq) { dev_err(arizona->dev, "Failed to add core IRQ domain\n"); ret = -EINVAL; goto err; } ret = regmap_add_irq_chip(arizona->regmap, irq_create_mapping(arizona->virq, 0), IRQF_ONESHOT, 0, aod, &arizona->aod_irq_chip); if (ret != 0) { dev_err(arizona->dev, "Failed to add AOD IRQs: %d\n", ret); goto err_domain; } ret = regmap_add_irq_chip(arizona->regmap, irq_create_mapping(arizona->virq, 1), IRQF_ONESHOT, 0, irq, &arizona->irq_chip); if (ret != 0) { dev_err(arizona->dev, "Failed to add main IRQs: %d\n", ret); goto err_aod; } /* Make sure the boot done IRQ is unmasked for resumes */ i = arizona_map_irq(arizona, ARIZONA_IRQ_BOOT_DONE); ret = request_threaded_irq(i, NULL, arizona_boot_done, IRQF_ONESHOT, "Boot done", arizona); if (ret != 0) { dev_err(arizona->dev, "Failed to request boot done %d: %d\n", arizona->irq, ret); goto err_boot_done; } /* Handle control interface errors in the core */ if (arizona->ctrlif_error) { i = arizona_map_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR); ret = request_threaded_irq(i, NULL, arizona_ctrlif_err, IRQF_ONESHOT, "Control interface error", arizona); if (ret != 0) { dev_err(arizona->dev, "Failed to request CTRLIF_ERR %d: %d\n", arizona->irq, ret); goto err_ctrlif; } } /* Used to emulate edge trigger and to work around broken pinmux */ if (arizona->pdata.irq_gpio) { if (gpio_to_irq(arizona->pdata.irq_gpio) != arizona->irq) { dev_warn(arizona->dev, "IRQ %d is not GPIO %d (%d)\n", arizona->irq, arizona->pdata.irq_gpio, gpio_to_irq(arizona->pdata.irq_gpio)); arizona->irq = gpio_to_irq(arizona->pdata.irq_gpio); } ret = devm_gpio_request_one(arizona->dev, arizona->pdata.irq_gpio, GPIOF_IN, "arizona IRQ"); if (ret != 0) { dev_err(arizona->dev, "Failed to request IRQ GPIO %d:: %d\n", arizona->pdata.irq_gpio, ret); arizona->pdata.irq_gpio = 0; } } ret = request_threaded_irq(arizona->irq, NULL, arizona_irq_thread, flags, "arizona", arizona); if (ret != 0) { dev_err(arizona->dev, "Failed to request primary IRQ %d: %d\n", arizona->irq, ret); goto err_main_irq; } return 0; err_main_irq: if (arizona->ctrlif_error) free_irq(arizona_map_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR), arizona); err_ctrlif: free_irq(arizona_map_irq(arizona, ARIZONA_IRQ_BOOT_DONE), arizona); err_boot_done: regmap_del_irq_chip(irq_create_mapping(arizona->virq, 1), arizona->irq_chip); err_aod: regmap_del_irq_chip(irq_create_mapping(arizona->virq, 0), arizona->aod_irq_chip); err_domain: err: return ret; }
int mc13xxx_common_init(struct device *dev) { struct mc13xxx_platform_data *pdata = dev_get_platdata(dev); struct mc13xxx *mc13xxx = dev_get_drvdata(dev); u32 revision; int i, ret; mc13xxx->dev = dev; ret = mc13xxx_reg_read(mc13xxx, MC13XXX_REVISION, &revision); if (ret) return ret; mc13xxx->variant->print_revision(mc13xxx, revision); ret = mc13xxx_reg_rmw(mc13xxx, MC13XXX_PWRCTRL, MC13XXX_PWRCTRL_WDIRESET, MC13XXX_PWRCTRL_WDIRESET); if (ret) return ret; for (i = 0; i < ARRAY_SIZE(mc13xxx->irqs); i++) { mc13xxx->irqs[i].reg_offset = i / MC13XXX_IRQ_PER_REG; mc13xxx->irqs[i].mask = BIT(i % MC13XXX_IRQ_PER_REG); } mc13xxx->irq_chip.name = dev_name(dev); mc13xxx->irq_chip.status_base = MC13XXX_IRQSTAT0; mc13xxx->irq_chip.mask_base = MC13XXX_IRQMASK0; mc13xxx->irq_chip.ack_base = MC13XXX_IRQSTAT0; mc13xxx->irq_chip.irq_reg_stride = MC13XXX_IRQSTAT1 - MC13XXX_IRQSTAT0; mc13xxx->irq_chip.init_ack_masked = true; mc13xxx->irq_chip.use_ack = true; mc13xxx->irq_chip.num_regs = MC13XXX_IRQ_REG_CNT; mc13xxx->irq_chip.irqs = mc13xxx->irqs; mc13xxx->irq_chip.num_irqs = ARRAY_SIZE(mc13xxx->irqs); ret = regmap_add_irq_chip(mc13xxx->regmap, mc13xxx->irq, IRQF_ONESHOT, 0, &mc13xxx->irq_chip, &mc13xxx->irq_data); if (ret) return ret; mutex_init(&mc13xxx->lock); if (mc13xxx_probe_flags_dt(mc13xxx) < 0 && pdata) mc13xxx->flags = pdata->flags; if (pdata) { mc13xxx_add_subdevice_pdata(mc13xxx, "%s-regulator", &pdata->regulators, sizeof(pdata->regulators)); mc13xxx_add_subdevice_pdata(mc13xxx, "%s-led", pdata->leds, sizeof(*pdata->leds)); mc13xxx_add_subdevice_pdata(mc13xxx, "%s-pwrbutton", pdata->buttons, sizeof(*pdata->buttons)); if (mc13xxx->flags & MC13XXX_USE_CODEC) mc13xxx_add_subdevice_pdata(mc13xxx, "%s-codec", pdata->codec, sizeof(*pdata->codec)); if (mc13xxx->flags & MC13XXX_USE_TOUCHSCREEN) mc13xxx_add_subdevice_pdata(mc13xxx, "%s-ts", &pdata->touch, sizeof(pdata->touch)); } else { mc13xxx_add_subdevice(mc13xxx, "%s-regulator"); mc13xxx_add_subdevice(mc13xxx, "%s-led"); mc13xxx_add_subdevice(mc13xxx, "%s-pwrbutton"); if (mc13xxx->flags & MC13XXX_USE_CODEC) mc13xxx_add_subdevice(mc13xxx, "%s-codec"); if (mc13xxx->flags & MC13XXX_USE_TOUCHSCREEN) mc13xxx_add_subdevice(mc13xxx, "%s-ts"); } if (mc13xxx->flags & MC13XXX_USE_ADC) mc13xxx_add_subdevice(mc13xxx, "%s-adc"); if (mc13xxx->flags & MC13XXX_USE_RTC) mc13xxx_add_subdevice(mc13xxx, "%s-rtc"); return 0; }
static int max77693_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct max77693_dev *max77693; unsigned int reg_data; int ret = 0; max77693 = devm_kzalloc(&i2c->dev, sizeof(struct max77693_dev), GFP_KERNEL); if (max77693 == NULL) return -ENOMEM; i2c_set_clientdata(i2c, max77693); max77693->dev = &i2c->dev; max77693->i2c = i2c; max77693->irq = i2c->irq; max77693->type = id->driver_data; max77693->regmap = devm_regmap_init_i2c(i2c, &max77693_regmap_config); if (IS_ERR(max77693->regmap)) { ret = PTR_ERR(max77693->regmap); dev_err(max77693->dev, "failed to allocate register map: %d\n", ret); return ret; } ret = regmap_read(max77693->regmap, MAX77693_PMIC_REG_PMIC_ID2, ®_data); if (ret < 0) { dev_err(max77693->dev, "device not found on this channel\n"); return ret; } else dev_info(max77693->dev, "device ID: 0x%x\n", reg_data); max77693->muic = i2c_new_dummy(i2c->adapter, I2C_ADDR_MUIC); if (!max77693->muic) { dev_err(max77693->dev, "Failed to allocate I2C device for MUIC\n"); return -ENODEV; } i2c_set_clientdata(max77693->muic, max77693); max77693->haptic = i2c_new_dummy(i2c->adapter, I2C_ADDR_HAPTIC); if (!max77693->haptic) { dev_err(max77693->dev, "Failed to allocate I2C device for Haptic\n"); ret = -ENODEV; goto err_i2c_haptic; } i2c_set_clientdata(max77693->haptic, max77693); max77693->regmap_haptic = devm_regmap_init_i2c(max77693->haptic, &max77693_regmap_haptic_config); if (IS_ERR(max77693->regmap_haptic)) { ret = PTR_ERR(max77693->regmap_haptic); dev_err(max77693->dev, "failed to initialize haptic register map: %d\n", ret); goto err_regmap; } /* * Initialize register map for MUIC device because use regmap-muic * instance of MUIC device when irq of max77693 is initialized * before call max77693-muic probe() function. */ max77693->regmap_muic = devm_regmap_init_i2c(max77693->muic, &max77693_regmap_muic_config); if (IS_ERR(max77693->regmap_muic)) { ret = PTR_ERR(max77693->regmap_muic); dev_err(max77693->dev, "failed to allocate register map: %d\n", ret); goto err_regmap; } ret = regmap_add_irq_chip(max77693->regmap, max77693->irq, IRQF_ONESHOT | IRQF_SHARED | IRQF_TRIGGER_FALLING, 0, &max77693_led_irq_chip, &max77693->irq_data_led); if (ret) { dev_err(max77693->dev, "failed to add irq chip: %d\n", ret); goto err_regmap; } ret = regmap_add_irq_chip(max77693->regmap, max77693->irq, IRQF_ONESHOT | IRQF_SHARED | IRQF_TRIGGER_FALLING, 0, &max77693_topsys_irq_chip, &max77693->irq_data_topsys); if (ret) { dev_err(max77693->dev, "failed to add irq chip: %d\n", ret); goto err_irq_topsys; } ret = regmap_add_irq_chip(max77693->regmap, max77693->irq, IRQF_ONESHOT | IRQF_SHARED | IRQF_TRIGGER_FALLING, 0, &max77693_charger_irq_chip, &max77693->irq_data_charger); if (ret) { dev_err(max77693->dev, "failed to add irq chip: %d\n", ret); goto err_irq_charger; } ret = regmap_add_irq_chip(max77693->regmap_muic, max77693->irq, IRQF_ONESHOT | IRQF_SHARED | IRQF_TRIGGER_FALLING, 0, &max77693_muic_irq_chip, &max77693->irq_data_muic); if (ret) { dev_err(max77693->dev, "failed to add irq chip: %d\n", ret); goto err_irq_muic; } /* Unmask interrupts from all blocks in interrupt source register */ ret = regmap_update_bits(max77693->regmap, MAX77693_PMIC_REG_INTSRC_MASK, SRC_IRQ_ALL, (unsigned int)~SRC_IRQ_ALL); if (ret < 0) { dev_err(max77693->dev, "Could not unmask interrupts in INTSRC: %d\n", ret); goto err_intsrc; } pm_runtime_set_active(max77693->dev); ret = mfd_add_devices(max77693->dev, -1, max77693_devs, ARRAY_SIZE(max77693_devs), NULL, 0, NULL); if (ret < 0) goto err_mfd; return ret; err_mfd: mfd_remove_devices(max77693->dev); err_intsrc: regmap_del_irq_chip(max77693->irq, max77693->irq_data_muic); err_irq_muic: regmap_del_irq_chip(max77693->irq, max77693->irq_data_charger); err_irq_charger: regmap_del_irq_chip(max77693->irq, max77693->irq_data_topsys); err_irq_topsys: regmap_del_irq_chip(max77693->irq, max77693->irq_data_led); err_regmap: i2c_unregister_device(max77693->haptic); err_i2c_haptic: i2c_unregister_device(max77693->muic); return ret; }
static int max77686_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct max77686_dev *max77686 = NULL; struct max77686_platform_data *pdata = dev_get_platdata(&i2c->dev); const struct of_device_id *match; unsigned int data; int ret = 0; const struct regmap_config *config; const struct regmap_irq_chip *irq_chip; const struct regmap_irq_chip *rtc_irq_chip; struct regmap **rtc_regmap; const struct mfd_cell *cells; int n_devs; if (IS_ENABLED(CONFIG_OF) && i2c->dev.of_node && !pdata) pdata = max77686_i2c_parse_dt_pdata(&i2c->dev); if (!pdata) { dev_err(&i2c->dev, "No platform data found.\n"); return -EINVAL; } max77686 = devm_kzalloc(&i2c->dev, sizeof(struct max77686_dev), GFP_KERNEL); if (!max77686) return -ENOMEM; if (i2c->dev.of_node) { match = of_match_node(max77686_pmic_dt_match, i2c->dev.of_node); if (!match) return -EINVAL; max77686->type = (unsigned long)match->data; } else max77686->type = id->driver_data; i2c_set_clientdata(i2c, max77686); max77686->dev = &i2c->dev; max77686->i2c = i2c; max77686->wakeup = pdata->wakeup; max77686->irq = i2c->irq; if (max77686->type == TYPE_MAX77686) { config = &max77686_regmap_config; irq_chip = &max77686_irq_chip; rtc_irq_chip = &max77686_rtc_irq_chip; rtc_regmap = &max77686->rtc_regmap; cells = max77686_devs; n_devs = ARRAY_SIZE(max77686_devs); } else { config = &max77802_regmap_config; irq_chip = &max77802_irq_chip; rtc_irq_chip = &max77802_rtc_irq_chip; rtc_regmap = &max77686->regmap; cells = max77802_devs; n_devs = ARRAY_SIZE(max77802_devs); } max77686->regmap = devm_regmap_init_i2c(i2c, config); if (IS_ERR(max77686->regmap)) { ret = PTR_ERR(max77686->regmap); dev_err(max77686->dev, "Failed to allocate register map: %d\n", ret); return ret; } ret = regmap_read(max77686->regmap, MAX77686_REG_DEVICE_ID, &data); if (ret < 0) { dev_err(max77686->dev, "device not found on this channel (this is not an error)\n"); return -ENODEV; } if (max77686->type == TYPE_MAX77686) { max77686->rtc = i2c_new_dummy(i2c->adapter, I2C_ADDR_RTC); if (!max77686->rtc) { dev_err(max77686->dev, "Failed to allocate I2C device for RTC\n"); return -ENODEV; } i2c_set_clientdata(max77686->rtc, max77686); max77686->rtc_regmap = devm_regmap_init_i2c(max77686->rtc, &max77686_rtc_regmap_config); if (IS_ERR(max77686->rtc_regmap)) { ret = PTR_ERR(max77686->rtc_regmap); dev_err(max77686->dev, "failed to allocate RTC regmap: %d\n", ret); goto err_unregister_i2c; } } ret = regmap_add_irq_chip(max77686->regmap, max77686->irq, IRQF_TRIGGER_FALLING | IRQF_ONESHOT | IRQF_SHARED, 0, irq_chip, &max77686->irq_data); if (ret) { dev_err(&i2c->dev, "failed to add PMIC irq chip: %d\n", ret); goto err_unregister_i2c; } ret = regmap_add_irq_chip(*rtc_regmap, max77686->irq, IRQF_TRIGGER_FALLING | IRQF_ONESHOT | IRQF_SHARED, 0, rtc_irq_chip, &max77686->rtc_irq_data); if (ret) { dev_err(&i2c->dev, "failed to add RTC irq chip: %d\n", ret); goto err_del_irqc; } ret = mfd_add_devices(max77686->dev, -1, cells, n_devs, NULL, 0, NULL); if (ret < 0) { dev_err(&i2c->dev, "failed to add MFD devices: %d\n", ret); goto err_del_rtc_irqc; } return 0; err_del_rtc_irqc: regmap_del_irq_chip(max77686->irq, max77686->rtc_irq_data); err_del_irqc: regmap_del_irq_chip(max77686->irq, max77686->irq_data); err_unregister_i2c: if (max77686->type == TYPE_MAX77686) i2c_unregister_device(max77686->rtc); return ret; }
static int palmas_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct palmas *palmas; struct palmas_platform_data *pdata; struct device_node *node = i2c->dev.of_node; int ret = 0, i; unsigned int reg, addr; int slave; struct mfd_cell *children; pdata = dev_get_platdata(&i2c->dev); if (node && !pdata) { pdata = devm_kzalloc(&i2c->dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) return -ENOMEM; palmas_dt_to_pdata(node, pdata); } if (!pdata) return -EINVAL; palmas = devm_kzalloc(&i2c->dev, sizeof(struct palmas), GFP_KERNEL); if (palmas == NULL) return -ENOMEM; i2c_set_clientdata(i2c, palmas); palmas->dev = &i2c->dev; palmas->id = id->driver_data; palmas->irq = i2c->irq; for (i = 0; i < PALMAS_NUM_CLIENTS; i++) { if (i == 0) palmas->i2c_clients[i] = i2c; else { palmas->i2c_clients[i] = i2c_new_dummy(i2c->adapter, i2c->addr + i); if (!palmas->i2c_clients[i]) { dev_err(palmas->dev, "can't attach client %d\n", i); ret = -ENOMEM; goto err; } } palmas->regmap[i] = devm_regmap_init_i2c(palmas->i2c_clients[i], &palmas_regmap_config[i]); if (IS_ERR(palmas->regmap[i])) { ret = PTR_ERR(palmas->regmap[i]); dev_err(palmas->dev, "Failed to allocate regmap %d, err: %d\n", i, ret); goto err; } } /* Change IRQ into clear on read mode for efficiency */ slave = PALMAS_BASE_TO_SLAVE(PALMAS_INTERRUPT_BASE); addr = PALMAS_BASE_TO_REG(PALMAS_INTERRUPT_BASE, PALMAS_INT_CTRL); reg = PALMAS_INT_CTRL_INT_CLEAR; regmap_write(palmas->regmap[slave], addr, reg); ret = regmap_add_irq_chip(palmas->regmap[slave], palmas->irq, IRQF_ONESHOT | IRQF_TRIGGER_LOW, 0, &palmas_irq_chip, &palmas->irq_data); if (ret < 0) goto err; slave = PALMAS_BASE_TO_SLAVE(PALMAS_PU_PD_OD_BASE); addr = PALMAS_BASE_TO_REG(PALMAS_PU_PD_OD_BASE, PALMAS_PRIMARY_SECONDARY_PAD1); if (pdata->mux_from_pdata) { reg = pdata->pad1; ret = regmap_write(palmas->regmap[slave], addr, reg); if (ret) goto err_irq; } else { ret = regmap_read(palmas->regmap[slave], addr, ®); if (ret) goto err_irq; } if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_0)) palmas->gpio_muxed |= PALMAS_GPIO_0_MUXED; if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_1_MASK)) palmas->gpio_muxed |= PALMAS_GPIO_1_MUXED; else if ((reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_1_MASK) == (2 << PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_1_SHIFT)) palmas->led_muxed |= PALMAS_LED1_MUXED; else if ((reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_1_MASK) == (3 << PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_1_SHIFT)) palmas->pwm_muxed |= PALMAS_PWM1_MUXED; if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_2_MASK)) palmas->gpio_muxed |= PALMAS_GPIO_2_MUXED; else if ((reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_2_MASK) == (2 << PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_2_SHIFT)) palmas->led_muxed |= PALMAS_LED2_MUXED; else if ((reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_2_MASK) == (3 << PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_2_SHIFT)) palmas->pwm_muxed |= PALMAS_PWM2_MUXED; if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_3)) palmas->gpio_muxed |= PALMAS_GPIO_3_MUXED; addr = PALMAS_BASE_TO_REG(PALMAS_PU_PD_OD_BASE, PALMAS_PRIMARY_SECONDARY_PAD2); if (pdata->mux_from_pdata) { reg = pdata->pad2; ret = regmap_write(palmas->regmap[slave], addr, reg); if (ret) goto err_irq; } else { ret = regmap_read(palmas->regmap[slave], addr, ®); if (ret) goto err_irq; } if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_4)) palmas->gpio_muxed |= PALMAS_GPIO_4_MUXED; if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_5_MASK)) palmas->gpio_muxed |= PALMAS_GPIO_5_MUXED; if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_6)) palmas->gpio_muxed |= PALMAS_GPIO_6_MUXED; if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_7_MASK)) palmas->gpio_muxed |= PALMAS_GPIO_7_MUXED; dev_info(palmas->dev, "Muxing GPIO %x, PWM %x, LED %x\n", palmas->gpio_muxed, palmas->pwm_muxed, palmas->led_muxed); reg = pdata->power_ctrl; slave = PALMAS_BASE_TO_SLAVE(PALMAS_PMU_CONTROL_BASE); addr = PALMAS_BASE_TO_REG(PALMAS_PMU_CONTROL_BASE, PALMAS_POWER_CTRL); ret = regmap_write(palmas->regmap[slave], addr, reg); if (ret) goto err_irq; /* * If we are probing with DT do this the DT way and return here * otherwise continue and add devices using mfd helpers. */ if (node) { ret = of_platform_populate(node, NULL, NULL, &i2c->dev); if (ret < 0) goto err_irq; else return ret; } children = kmemdup(palmas_children, sizeof(palmas_children), GFP_KERNEL); if (!children) { ret = -ENOMEM; goto err_irq; } children[PALMAS_PMIC_ID].platform_data = pdata->pmic_pdata; children[PALMAS_PMIC_ID].pdata_size = sizeof(*pdata->pmic_pdata); children[PALMAS_GPADC_ID].platform_data = pdata->gpadc_pdata; children[PALMAS_GPADC_ID].pdata_size = sizeof(*pdata->gpadc_pdata); children[PALMAS_RESOURCE_ID].platform_data = pdata->resource_pdata; children[PALMAS_RESOURCE_ID].pdata_size = sizeof(*pdata->resource_pdata); children[PALMAS_USB_ID].platform_data = pdata->usb_pdata; children[PALMAS_USB_ID].pdata_size = sizeof(*pdata->usb_pdata); children[PALMAS_CLK_ID].platform_data = pdata->clk_pdata; children[PALMAS_CLK_ID].pdata_size = sizeof(*pdata->clk_pdata); ret = mfd_add_devices(palmas->dev, -1, children, ARRAY_SIZE(palmas_children), NULL, 0, regmap_irq_get_domain(palmas->irq_data)); kfree(children); if (ret < 0) goto err_devices; return ret; err_devices: mfd_remove_devices(palmas->dev); err_irq: regmap_del_irq_chip(palmas->irq, palmas->irq_data); err: return ret; }
static int madera_irq_probe(struct platform_device *pdev) { struct madera *madera = dev_get_drvdata(pdev->dev.parent); struct irq_data *irq_data; unsigned int irq_flags = 0; int ret; dev_dbg(&pdev->dev, "probe\n"); /* * Read the flags from the interrupt controller if not specified * by pdata */ irq_flags = madera->pdata.irq_flags; if (!irq_flags) { irq_data = irq_get_irq_data(madera->irq); if (!irq_data) { dev_err(&pdev->dev, "Invalid IRQ: %d\n", madera->irq); return -EINVAL; } irq_flags = irqd_get_trigger_type(irq_data); /* Codec defaults to trigger low, use this if no flags given */ if (irq_flags == IRQ_TYPE_NONE) irq_flags = IRQF_TRIGGER_LOW; } if (irq_flags & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) { dev_err(&pdev->dev, "Host interrupt not level-triggered\n"); return -EINVAL; } /* * The silicon always starts at active-low, check if we need to * switch to active-high. */ if (irq_flags & IRQF_TRIGGER_HIGH) { ret = regmap_update_bits(madera->regmap, MADERA_IRQ1_CTRL, MADERA_IRQ_POL_MASK, 0); if (ret) { dev_err(&pdev->dev, "Failed to set IRQ polarity: %d\n", ret); return ret; } } /* * NOTE: regmap registers this against the OF node of the parent of * the regmap - that is, against the mfd driver */ ret = regmap_add_irq_chip(madera->regmap, madera->irq, IRQF_ONESHOT, 0, &madera_irq_chip, &madera->irq_data); if (ret) { dev_err(&pdev->dev, "add_irq_chip failed: %d\n", ret); return ret; } /* Save dev in parent MFD struct so it is accessible to siblings */ madera->irq_dev = &pdev->dev; return 0; }