static int wm8350_wdt_set_timeout(struct watchdog_device *wdt_dev, unsigned int timeout) { struct wm8350 *wm8350 = watchdog_get_drvdata(wdt_dev); int ret, i; u16 reg; for (i = 0; i < ARRAY_SIZE(wm8350_wdt_cfgs); i++) if (wm8350_wdt_cfgs[i].time == timeout) break; if (i == ARRAY_SIZE(wm8350_wdt_cfgs)) return -EINVAL; mutex_lock(&wdt_mutex); wm8350_reg_unlock(wm8350); reg = wm8350_reg_read(wm8350, WM8350_SYSTEM_CONTROL_2); reg &= ~WM8350_WDOG_TO_MASK; reg |= wm8350_wdt_cfgs[i].val; ret = wm8350_reg_write(wm8350, WM8350_SYSTEM_CONTROL_2, reg); wm8350_reg_lock(wm8350); mutex_unlock(&wdt_mutex); wdt_dev->timeout = timeout; return ret; }
static __devinit int wm8350_power_probe(struct platform_device *pdev) { struct wm8350 *wm8350 = platform_get_drvdata(pdev); struct wm8350_power *power = &wm8350->power; struct wm8350_charger_policy *policy = power->policy; struct power_supply *usb = &power->usb; struct power_supply *battery = &power->battery; struct power_supply *ac = &power->ac; int ret; ac->name = "wm8350-ac"; ac->type = POWER_SUPPLY_TYPE_MAINS; ac->properties = wm8350_ac_props; ac->num_properties = ARRAY_SIZE(wm8350_ac_props); ac->get_property = wm8350_ac_get_prop; ret = power_supply_register(&pdev->dev, ac); if (ret) return ret; battery->name = "wm8350-battery"; battery->properties = wm8350_bat_props; battery->num_properties = ARRAY_SIZE(wm8350_bat_props); battery->get_property = wm8350_bat_get_property; battery->use_for_apm = 1; ret = power_supply_register(&pdev->dev, battery); if (ret) goto battery_failed; usb->name = "wm8350-usb", usb->type = POWER_SUPPLY_TYPE_USB; usb->properties = wm8350_usb_props; usb->num_properties = ARRAY_SIZE(wm8350_usb_props); usb->get_property = wm8350_usb_get_prop; ret = power_supply_register(&pdev->dev, usb); if (ret) goto usb_failed; ret = device_create_file(&pdev->dev, &dev_attr_charger_state); if (ret < 0) dev_warn(wm8350->dev, "failed to add charge sysfs: %d\n", ret); ret = 0; wm8350_init_charger(wm8350); if (wm8350_charger_config(wm8350, policy) == 0) { wm8350_reg_unlock(wm8350); wm8350_set_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CHG_ENA); wm8350_reg_lock(wm8350); } return ret; usb_failed: power_supply_unregister(battery); battery_failed: power_supply_unregister(ac); return ret; }
static irqreturn_t wm8350_charger_handler(int irq, void *data) { struct wm8350 *wm8350 = data; struct wm8350_power *power = &wm8350->power; struct wm8350_charger_policy *policy = power->policy; switch (irq - wm8350->irq_base) { case WM8350_IRQ_CHG_BAT_FAIL: dev_err(wm8350->dev, "battery failed\n"); break; case WM8350_IRQ_CHG_TO: dev_err(wm8350->dev, "charger timeout\n"); power_supply_changed(&power->battery); break; case WM8350_IRQ_CHG_BAT_HOT: case WM8350_IRQ_CHG_BAT_COLD: case WM8350_IRQ_CHG_START: case WM8350_IRQ_CHG_END: power_supply_changed(&power->battery); break; case WM8350_IRQ_CHG_FAST_RDY: dev_dbg(wm8350->dev, "fast charger ready\n"); wm8350_charger_config(wm8350, policy); wm8350_reg_unlock(wm8350); wm8350_set_bits(wm8350, WM8350_BATTERY_CHARGER_CONTROL_1, WM8350_CHG_FAST); wm8350_reg_lock(wm8350); break; case WM8350_IRQ_CHG_VBATT_LT_3P9: dev_warn(wm8350->dev, "battery < 3.9V\n"); break; case WM8350_IRQ_CHG_VBATT_LT_3P1: dev_warn(wm8350->dev, "battery < 3.1V\n"); break; case WM8350_IRQ_CHG_VBATT_LT_2P85: dev_warn(wm8350->dev, "battery < 2.85V\n"); break; /* Supply change. We will overnotify but it should do * no harm. */ case WM8350_IRQ_EXT_USB_FB: case WM8350_IRQ_EXT_WALL_FB: wm8350_charger_config(wm8350, policy); case WM8350_IRQ_EXT_BAT_FB: /* Fall through */ power_supply_changed(&power->battery); power_supply_changed(&power->usb); power_supply_changed(&power->ac); break; default: dev_err(wm8350->dev, "Unknown interrupt %d\n", irq); } return IRQ_HANDLED; }
static void wm8350_charger_handler(struct wm8350 *wm8350, int irq, void *data) { struct wm8350_power *power = &wm8350->power; struct wm8350_charger_policy *policy = power->policy; switch (irq) { case WM8350_IRQ_CHG_BAT_FAIL: dev_err(wm8350->dev, "battery failed\n"); break; case WM8350_IRQ_CHG_TO: dev_err(wm8350->dev, "charger timeout\n"); power_supply_changed(&power->battery); break; case WM8350_IRQ_CHG_BAT_HOT: case WM8350_IRQ_CHG_BAT_COLD: case WM8350_IRQ_CHG_START: case WM8350_IRQ_CHG_END: power_supply_changed(&power->battery); break; case WM8350_IRQ_CHG_FAST_RDY: dev_dbg(wm8350->dev, "fast charger ready\n"); wm8350_charger_config(wm8350, policy); wm8350_reg_unlock(wm8350); wm8350_set_bits(wm8350, WM8350_BATTERY_CHARGER_CONTROL_1, WM8350_CHG_FAST); wm8350_reg_lock(wm8350); break; case WM8350_IRQ_CHG_VBATT_LT_3P9: dev_warn(wm8350->dev, "battery < 3.9V\n"); break; case WM8350_IRQ_CHG_VBATT_LT_3P1: dev_warn(wm8350->dev, "battery < 3.1V\n"); break; case WM8350_IRQ_CHG_VBATT_LT_2P85: dev_warn(wm8350->dev, "battery < 2.85V\n"); break; case WM8350_IRQ_EXT_USB_FB: case WM8350_IRQ_EXT_WALL_FB: wm8350_charger_config(wm8350, policy); case WM8350_IRQ_EXT_BAT_FB: power_supply_changed(&power->battery); power_supply_changed(&power->usb); power_supply_changed(&power->ac); break; default: dev_err(wm8350->dev, "Unknown interrupt %d\n", irq); } }
static int wm8350_charger_config(struct wm8350 *wm8350, struct wm8350_charger_policy *policy) { u16 reg, eoc_mA, fast_limit_mA; if (!policy) { dev_warn(wm8350->dev, "No charger policy, charger not configured.\n"); return -EINVAL; } /* make sure USB fast charge current is not > 500mA */ if (policy->fast_limit_USB_mA > 500) { dev_err(wm8350->dev, "USB fast charge > 500mA\n"); return -EINVAL; } eoc_mA = WM8350_CHG_EOC_mA(policy->eoc_mA); wm8350_reg_unlock(wm8350); reg = wm8350_reg_read(wm8350, WM8350_BATTERY_CHARGER_CONTROL_1) & WM8350_CHG_ENA_R168; wm8350_reg_write(wm8350, WM8350_BATTERY_CHARGER_CONTROL_1, reg | eoc_mA | policy->trickle_start_mV | WM8350_CHG_TRICKLE_TEMP_CHOKE | WM8350_CHG_TRICKLE_USB_CHOKE | WM8350_CHG_FAST_USB_THROTTLE); if (wm8350_get_supplies(wm8350) & WM8350_USB_SUPPLY) { fast_limit_mA = WM8350_CHG_FAST_LIMIT_mA(policy->fast_limit_USB_mA); wm8350_reg_write(wm8350, WM8350_BATTERY_CHARGER_CONTROL_2, policy->charge_mV | policy->trickle_charge_USB_mA | fast_limit_mA | wm8350_charge_time_min(wm8350, policy->charge_timeout)); } else { fast_limit_mA = WM8350_CHG_FAST_LIMIT_mA(policy->fast_limit_mA); wm8350_reg_write(wm8350, WM8350_BATTERY_CHARGER_CONTROL_2, policy->charge_mV | policy->trickle_charge_mA | fast_limit_mA | wm8350_charge_time_min(wm8350, policy->charge_timeout)); } wm8350_reg_lock(wm8350); return 0; }
static int gpio_set_dir(struct wm8350 *wm8350, int gpio, int dir) { int ret; wm8350_reg_unlock(wm8350); if (dir == WM8350_GPIO_DIR_OUT) ret = wm8350_clear_bits(wm8350, WM8350_GPIO_CONFIGURATION_I_O, 1 << gpio); else ret = wm8350_set_bits(wm8350, WM8350_GPIO_CONFIGURATION_I_O, 1 << gpio); wm8350_reg_lock(wm8350); return ret; }
static int wm8350_wdt_stop(struct wm8350 *wm8350) { int ret; u16 reg; mutex_lock(&wdt_mutex); wm8350_reg_unlock(wm8350); reg = wm8350_reg_read(wm8350, WM8350_SYSTEM_CONTROL_2); reg &= ~WM8350_WDOG_MODE_MASK; ret = wm8350_reg_write(wm8350, WM8350_SYSTEM_CONTROL_2, reg); wm8350_reg_lock(wm8350); mutex_unlock(&wdt_mutex); return ret; }
static int wm8350_wdt_set_timeout(struct wm8350 *wm8350, u16 value) { int ret; u16 reg; mutex_lock(&wdt_mutex); wm8350_reg_unlock(wm8350); reg = wm8350_reg_read(wm8350, WM8350_SYSTEM_CONTROL_2); reg &= ~WM8350_WDOG_TO_MASK; reg |= value; ret = wm8350_reg_write(wm8350, WM8350_SYSTEM_CONTROL_2, reg); wm8350_reg_lock(wm8350); mutex_unlock(&wdt_mutex); return ret; }
static int wm8350_wdt_stop(struct watchdog_device *wdt_dev) { struct wm8350 *wm8350 = watchdog_get_drvdata(wdt_dev); int ret; u16 reg; mutex_lock(&wdt_mutex); wm8350_reg_unlock(wm8350); reg = wm8350_reg_read(wm8350, WM8350_SYSTEM_CONTROL_2); reg &= ~WM8350_WDOG_MODE_MASK; ret = wm8350_reg_write(wm8350, WM8350_SYSTEM_CONTROL_2, reg); wm8350_reg_lock(wm8350); mutex_unlock(&wdt_mutex); return ret; }
//static int wm8350_init(struct wm8350 *wm8350) int wm8350_dev_init(struct wm8350 *wm8350) { int i, ret; u16 data; #if 0 /* dont assert RTS when hibernating */ wm8350_set_bits(wm8350, WM8350_SYSTEM_HIBERNATE, WM8350_RST_HIB_MODE); #endif wm8350_reg_unlock(wm8350); wm8350_set_bits(wm8350, WM8350_SYSTEM_CONTROL_1, WM8350_IRQ_POL); wm8350_reg_lock(wm8350); s3c2410_gpio_pullup(S3C2410_GPF1, 0); s3c2410_gpio_cfgpin(S3C2410_GPF1, S3C2410_GPF1_EINT1); // set_irq_type(IRQ_EINT1, IRQT_BOTHEDGE); s3c2410_gpio_pullup(S3C2410_GPF2, 0); s3c2410_gpio_cfgpin(S3C2410_GPF2, S3C2410_GPF2_EINT2); /* Shutdown threshold value 3.1v off , 3.2v on */ wm8350_reg_unlock(wm8350); data = wm8350_reg_read(wm8350, WM8350_POWER_CHECK_COMPARATOR) & ~(WM8350_PCCMP_OFF_THR_MASK | WM8350_PCCMP_ON_THR_MASK); wm8350_reg_write(wm8350, WM8350_POWER_CHECK_COMPARATOR, data | 0x23); wm8350_reg_lock(wm8350); data = wm8350_reg_read(wm8350, WM8350_DIGITISER_CONTROL_2); wm8350_reg_write(wm8350, WM8350_DIGITISER_CONTROL_2, data | WM8350_AUXADC_CAL); config_s3c_wm8350_gpio(wm8350); #if 0 /* Sw1 --> PWR_ON */ wm8350_register_irq(wm8350, WM8350_IRQ_WKUP_ONKEY, imx32ads_switch_handler, NULL); wm8350_unmask_irq(wm8350, WM8350_IRQ_WKUP_ONKEY); #endif #ifndef CONFIG_MACH_CANOPUS for (i = 0; i < ARRAY_SIZE(wm8350_regulator_devices); i++) { platform_set_drvdata(&wm8350_regulator_devices[i], wm8350); ret = platform_device_register(&wm8350_regulator_devices[i]); if (ret < 0) goto unwind; } #else // CONFIG_MACH_CANOPUS struct regulator_init_data *reg_data = NULL; for (i = 0; i < ARRAY_SIZE(wm8350_regulator_devices); i++) { if (wm8350_regulator_devices[i].id == WM8350_DCDC_4) { // for LCD if (q_hw_ver(7800_ES2) || q_hw_ver(7800_TP) || q_hw_ver(7800_MP)) { reg_data = (struct regulator_init_data *)wm8350_regulator_devices[i].dev.platform_data; reg_data->constraints.min_uV = 3400000; reg_data->constraints.max_uV = 3400000; reg_data->constraints.state_mem.uV = 3400000; } } else if (wm8350_regulator_devices[i].id == WM8350_LDO_3) { // for PMIC LDO if (q_hw_ver(SWP2000) || q_hw_ver(7800_MP2) || q_hw_ver(KTQOOK_TP2) || q_hw_ver(KTQOOK_MP) || q_hw_ver(SKATM)) { reg_data = (struct regulator_init_data *)wm8350_regulator_devices[i].dev.platform_data; reg_data->constraints.min_uV = 1200000; reg_data->constraints.max_uV = 1200000; reg_data->num_consumer_supplies = ARRAY_SIZE(ldo4_consumers); reg_data->consumer_supplies = ldo4_consumers; } } else if (wm8350_regulator_devices[i].id == WM8350_LDO_4) { // for PMIC LDO if (q_hw_ver(SWP2000) || q_hw_ver(7800_MP2) || q_hw_ver(KTQOOK_TP2) || q_hw_ver(KTQOOK_MP) || q_hw_ver(SKATM)) { reg_data = (struct regulator_init_data *)wm8350_regulator_devices[i].dev.platform_data; reg_data->constraints.min_uV = 3300000; reg_data->constraints.max_uV = 3300000; reg_data->num_consumer_supplies = ARRAY_SIZE(ldo3_consumers); reg_data->consumer_supplies = ldo3_consumers; } } platform_set_drvdata(&wm8350_regulator_devices[i], wm8350); ret = platform_device_register(&wm8350_regulator_devices[i]); if (ret < 0) goto unwind; } #endif // CONFIG_MACH_CANOPUS /* now register other clients */ return s3c_wm8350_device_register(wm8350); unwind: for (i--; i >= 0; i--) platform_device_unregister(&wm8350_regulator_devices[i]); return ret; }
static int wm8350_rtc_probe(struct platform_device *pdev) { struct wm8350 *wm8350 = platform_get_drvdata(pdev); struct wm8350_rtc *wm_rtc = &wm8350->rtc; int ret = 0; u16 timectl, power5; timectl = wm8350_reg_read(wm8350, WM8350_RTC_TIME_CONTROL); if (timectl & WM8350_RTC_BCD) { dev_err(&pdev->dev, "RTC BCD mode not supported\n"); return -EINVAL; } if (timectl & WM8350_RTC_12HR) { dev_err(&pdev->dev, "RTC 12 hour mode not supported\n"); return -EINVAL; } /* enable the RTC if it's not already enabled */ power5 = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_5); if (!(power5 & WM8350_RTC_TICK_ENA)) { dev_info(wm8350->dev, "Starting RTC\n"); wm8350_reg_unlock(wm8350); ret = wm8350_set_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_RTC_TICK_ENA); if (ret < 0) { dev_err(&pdev->dev, "failed to enable RTC: %d\n", ret); return ret; } wm8350_reg_lock(wm8350); } if (timectl & WM8350_RTC_STS) { int retries; ret = wm8350_clear_bits(wm8350, WM8350_RTC_TIME_CONTROL, WM8350_RTC_SET); if (ret < 0) { dev_err(&pdev->dev, "failed to start: %d\n", ret); return ret; } retries = WM8350_SET_TIME_RETRIES; do { timectl = wm8350_reg_read(wm8350, WM8350_RTC_TIME_CONTROL); } while (timectl & WM8350_RTC_STS && --retries); if (retries == 0) { dev_err(&pdev->dev, "failed to start: timeout\n"); return -ENODEV; } } device_init_wakeup(&pdev->dev, 1); wm_rtc->rtc = devm_rtc_device_register(&pdev->dev, "wm8350", &wm8350_rtc_ops, THIS_MODULE); if (IS_ERR(wm_rtc->rtc)) { ret = PTR_ERR(wm_rtc->rtc); dev_err(&pdev->dev, "failed to register RTC: %d\n", ret); return ret; } wm8350_register_irq(wm8350, WM8350_IRQ_RTC_SEC, wm8350_rtc_update_handler, 0, "RTC Seconds", wm8350); wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC); wm8350_register_irq(wm8350, WM8350_IRQ_RTC_ALM, wm8350_rtc_alarm_handler, 0, "RTC Alarm", wm8350); return 0; }
static int gpio_set_func(struct wm8350 *wm8350, int gpio, int func) { u16 reg; wm8350_reg_unlock(wm8350); switch (gpio) { case 0: reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_1) & ~WM8350_GP0_FN_MASK; wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_1, reg | ((func & 0xf) << 0)); break; case 1: reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_1) & ~WM8350_GP1_FN_MASK; wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_1, reg | ((func & 0xf) << 4)); break; case 2: reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_1) & ~WM8350_GP2_FN_MASK; wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_1, reg | ((func & 0xf) << 8)); break; case 3: reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_1) & ~WM8350_GP3_FN_MASK; wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_1, reg | ((func & 0xf) << 12)); break; case 4: reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_2) & ~WM8350_GP4_FN_MASK; wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_2, reg | ((func & 0xf) << 0)); break; case 5: reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_2) & ~WM8350_GP5_FN_MASK; wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_2, reg | ((func & 0xf) << 4)); break; case 6: reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_2) & ~WM8350_GP6_FN_MASK; wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_2, reg | ((func & 0xf) << 8)); break; case 7: reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_2) & ~WM8350_GP7_FN_MASK; wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_2, reg | ((func & 0xf) << 12)); break; case 8: reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_3) & ~WM8350_GP8_FN_MASK; wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_3, reg | ((func & 0xf) << 0)); break; case 9: reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_3) & ~WM8350_GP9_FN_MASK; wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_3, reg | ((func & 0xf) << 4)); break; case 10: reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_3) & ~WM8350_GP10_FN_MASK; wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_3, reg | ((func & 0xf) << 8)); break; case 11: reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_3) & ~WM8350_GP11_FN_MASK; wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_3, reg | ((func & 0xf) << 12)); break; case 12: reg = wm8350_reg_read(wm8350, WM8350_GPIO_FUNCTION_SELECT_4) & ~WM8350_GP12_FN_MASK; wm8350_reg_write(wm8350, WM8350_GPIO_FUNCTION_SELECT_4, reg | ((func & 0xf) << 0)); break; default: wm8350_reg_lock(wm8350); return -EINVAL; } wm8350_reg_lock(wm8350); return 0; }
int wm8350_init(struct wm8350 *wm8350) { int ret = 0; /* register regulator and set constraints */ wm8350_device_register_pmic(wm8350); set_regulator_constraints(wm8350); #ifdef NOT_PORTED_TO_IMX37 wm8350_device_register_rtc(wm8350); wm8350_device_register_wdg(wm8350); wm8350_device_register_power(wm8350); #endif mxc_init_wm8350(); /*Note: Needs to be moved into a regulator function. */ /* Configuring -- GPIO 7 pin */ if (wm8350_gpio_config(wm8350, 7, WM8350_GPIO_DIR_OUT, 0, WM8350_GPIO_ACTIVE_LOW, WM8350_GPIO_PULL_NONE, WM8350_GPIO_INVERT_OFF, WM8350_GPIO_DEBOUNCE_OFF) == 0) wm8350_gpio_set_status(wm8350, 7, 1); else printk(KERN_ERR "Error in setting Wolfson GPIO pin 7 \n"); /* enable gpio4:USB_VBUS_EN */ ret = wm8350_gpio_config(wm8350, 4, WM8350_GPIO_DIR_IN, WM8350_GPIO4_MR_IN, WM8350_GPIO_ACTIVE_HIGH, WM8350_GPIO_PULL_UP, WM8350_GPIO_INVERT_OFF, WM8350_GPIO_DEBOUNCE_OFF); if (ret) printk(KERN_ERR "Error in setting USB VBUS enable pin\n"); /*PMIC RDY*/ if (wm8350_gpio_config(wm8350, 9, WM8350_GPIO_DIR_OUT, WM8350_GPIO9_GPIO_OUT, WM8350_GPIO_ACTIVE_LOW, WM8350_GPIO_PULL_NONE, WM8350_GPIO_INVERT_OFF, WM8350_GPIO_DEBOUNCE_OFF) == 0) wm8350_gpio_set_status(wm8350, 9, 1); else printk(KERN_ERR "Error in setting Wolfson GPIO pin 9 \n"); /* register sound */ printk("Registering imx37_snd_device"); imx_snd_device = platform_device_alloc("wm8350-imx-3stack-audio", -1); if (!imx_snd_device) { ret = -ENOMEM; goto err; } imx_snd_device->dev.platform_data = &imx_3stack_audio_platform_data; platform_set_drvdata(imx_snd_device, &wm8350->audio); ret = platform_device_add(imx_snd_device); if (ret) goto snd_err; /* set up PMIC IRQ (active high) to i.MX32ADS */ printk("Registering PMIC INT"); INIT_WORK(&wm8350->work, wm8350_irq_work); wm8350_reg_unlock(wm8350); wm8350_set_bits(wm8350, WM8350_SYSTEM_CONTROL_1, WM8350_IRQ_POL); wm8350_reg_lock(wm8350); set_irq_type(MXC_PMIC_INT_LINE, IRQT_RISING); ret = request_irq(MXC_PMIC_INT_LINE, wm8350_irq_handler, IRQF_DISABLED, "wm8350-pmic", wm8350); if (ret != 0) { printk(KERN_ERR "wm8350: cant request irq %d\n", MXC_PMIC_INT_LINE); goto err; } wm8350->nirq = MXC_PMIC_INT_LINE; set_irq_wake(MXC_PMIC_INT_LINE, 1); #ifdef NOT_PORTED_TO_IMX37 printk("Configuring WM8350 GPIOS"); config_gpios(wm8350); config_hibernate(wm8350); #endif /* Sw1 --> PWR_ON */ printk("Registering and unmasking the WM8350 wakeup key\n"); wm8350_register_irq(wm8350, WM8350_IRQ_WKUP_ONKEY, imx37_3stack_switch_handler, NULL); wm8350_unmask_irq(wm8350, WM8350_IRQ_WKUP_ONKEY); /* unmask all & clear sticky */ printk("Unmasking WM8350 local interrupts\n"); wm8350_reg_write(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK, 0x3ffe); schedule_work(&wm8350->work); #if BATTERY /* not much use without a battery atm */ wm8350_init_battery(wm8350); #endif printk("Exiting normally from wm8350_init()"); return ret; snd_err: platform_device_put(imx_snd_device); err: printk("wm8350_init() FAILED"); kfree(wm8350->reg_cache); return ret; }