/* * Handle commands from user-space */ static int wm8350_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) { struct wm8350_rtc *wm_rtc = to_wm8350_rtc_device(dev); struct wm8350 *wm8350 = to_wm8350_from_rtc(wm_rtc); switch (cmd) { case RTC_AIE_OFF: /* alarm off */ wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_ALM); wm_rtc->alarm_enabled = 0; break; case RTC_AIE_ON: /* alarm on */ wm8350_unmask_irq(wm8350, WM8350_IRQ_RTC_ALM); wm_rtc->alarm_enabled = 1; break; case RTC_UIE_OFF: /* update off */ wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC); wm_rtc->update_enabled = 0; break; case RTC_UIE_ON: /* update on */ wm8350_unmask_irq(wm8350, WM8350_IRQ_RTC_SEC); wm_rtc->update_enabled = 1; break; case RTC_PIE_ON: if (!wm_rtc->pie_enabled) { enable_irq(wm_rtc->per_irq); wm_rtc->pie_enabled = 1; } break; case RTC_PIE_OFF: if (wm_rtc->pie_enabled) { disable_irq(wm_rtc->per_irq); wm_rtc->pie_enabled = 0; } break; case RTC_IRQP_READ: /* read periodic alarm frequency */ return wm_rtc->pie_freq; case RTC_IRQP_SET: /* set periodic alarm frequency */ return wm8350_rtc_set_pie(wm_rtc, arg); default: return -ENOIOCTLCMD; } return 0; }
static void headphone_detect_handler(struct work_struct *work) { struct imx_3stack_priv *priv = &machine_priv; struct platform_device *pdev = priv->pdev; struct wm8350 *wm8350 = priv->wm8350; sysfs_notify(&pdev->dev.kobj, NULL, "headphone"); wm8350_unmask_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R); }
static int wm8350_regulator_probe(struct platform_device *pdev) { struct wm8350 *wm8350 = dev_get_drvdata(&pdev->dev); struct regulator_dev *rdev; int ret; u16 val; if (pdev->id < WM8350_DCDC_1 || pdev->id > WM8350_ISINK_B) return -ENODEV; /* do any regulatior specific init */ switch (pdev->id) { case WM8350_DCDC_1: val = wm8350_reg_read(wm8350, WM8350_DCDC1_LOW_POWER); wm8350->pmic.dcdc1_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK; break; case WM8350_DCDC_3: val = wm8350_reg_read(wm8350, WM8350_DCDC3_LOW_POWER); wm8350->pmic.dcdc3_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK; break; case WM8350_DCDC_4: val = wm8350_reg_read(wm8350, WM8350_DCDC4_LOW_POWER); wm8350->pmic.dcdc4_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK; break; case WM8350_DCDC_6: val = wm8350_reg_read(wm8350, WM8350_DCDC6_LOW_POWER); wm8350->pmic.dcdc6_hib_mode = val & WM8350_DCDC_HIB_MODE_MASK; break; } /* register regulator */ rdev = regulator_register(&wm8350_reg[pdev->id], &pdev->dev, pdev->dev.platform_data, dev_get_drvdata(&pdev->dev)); if (IS_ERR(rdev)) { dev_err(&pdev->dev, "failed to register %s\n", wm8350_reg[pdev->id].name); return PTR_ERR(rdev); } /* register regulator IRQ */ ret = wm8350_register_irq(wm8350, wm8350_reg[pdev->id].irq, pmic_uv_handler, rdev); if (ret < 0) { regulator_unregister(rdev); dev_err(&pdev->dev, "failed to register regulator %s IRQ\n", wm8350_reg[pdev->id].name); return ret; } wm8350_unmask_irq(wm8350, wm8350_reg[pdev->id].irq); return 0; }
static int config_gpios(struct wm8350 *wm8350) { /* power on */ wm8350_gpio_config(wm8350, 0, WM8350_GPIO_DIR_IN, WM8350_GPIO0_PWR_ON_IN, WM8350_GPIO_ACTIVE_LOW, WM8350_GPIO_PULL_UP, WM8350_GPIO_INVERT_OFF, WM8350_GPIO_DEBOUNCE_ON); /* Sw3 --> PWR_OFF_GPIO3 */ /* lg - TODO: GPIO1_0 to be pulled down */ wm8350_gpio_config(wm8350, 3, WM8350_GPIO_DIR_IN, WM8350_GPIO3_PWR_OFF_IN, WM8350_GPIO_ACTIVE_HIGH, WM8350_GPIO_PULL_DOWN, WM8350_GPIO_INVERT_OFF, WM8350_GPIO_DEBOUNCE_ON); /* MR or MEMRST ????? */ wm8350_gpio_config(wm8350, 4, WM8350_GPIO_DIR_IN, WM8350_GPIO4_MR_IN, WM8350_GPIO_ACTIVE_HIGH, WM8350_GPIO_PULL_DOWN, WM8350_GPIO_INVERT_OFF, WM8350_GPIO_DEBOUNCE_OFF); /* Hibernate -- GPIO 7 */ wm8350_gpio_config(wm8350, 7, WM8350_GPIO_DIR_IN, WM8350_GPIO7_HIBERNATE_IN, WM8350_GPIO_ACTIVE_HIGH, WM8350_GPIO_PULL_DOWN, WM8350_GPIO_INVERT_OFF, WM8350_GPIO_DEBOUNCE_OFF); /* SDOUT */ wm8350_gpio_config(wm8350, 6, WM8350_GPIO_DIR_OUT, WM8350_GPIO6_SDOUT_OUT, WM8350_GPIO_ACTIVE_HIGH, WM8350_GPIO_PULL_NONE, WM8350_GPIO_INVERT_OFF, WM8350_GPIO_DEBOUNCE_OFF); /* GPIO switch SW2 */ wm8350_gpio_config(wm8350, 7, WM8350_GPIO_DIR_IN, WM8350_GPIO7_GPIO_IN, WM8350_GPIO_ACTIVE_HIGH, WM8350_GPIO_PULL_DOWN, WM8350_GPIO_INVERT_OFF, WM8350_GPIO_DEBOUNCE_ON); wm8350_register_irq(wm8350, WM8350_IRQ_GPIO(7), imx37_3stack_switch_handler, NULL); wm8350_unmask_irq(wm8350, WM8350_IRQ_GPIO(7)); /* PWR_FAIL */ wm8350_gpio_config(wm8350, 8, WM8350_GPIO_DIR_OUT, WM8350_GPIO8_VCC_FAULT_OUT, WM8350_GPIO_ACTIVE_LOW, WM8350_GPIO_PULL_NONE, WM8350_GPIO_INVERT_OFF, WM8350_GPIO_DEBOUNCE_OFF); /* BATT Fault */ wm8350_gpio_config(wm8350, 9, WM8350_GPIO_DIR_OUT, WM8350_GPIO9_BATT_FAULT_OUT, WM8350_GPIO_ACTIVE_LOW, WM8350_GPIO_PULL_NONE, WM8350_GPIO_INVERT_OFF, WM8350_GPIO_DEBOUNCE_OFF); return 0; }
static int __devinit imx_3stack_wm8350_probe(struct platform_device *pdev) { struct mxc_audio_platform_data *plat = pdev->dev.platform_data; struct imx_3stack_priv *priv = &machine_priv; struct wm8350 *wm8350 = plat->priv; struct snd_soc_dai *wm8350_cpu_dai; int ret = 0; u16 reg; priv->pdev = pdev; priv->wm8350 = wm8350; gpio_activate_audio_ports(); imx_3stack_init_dam(plat->src_port, plat->ext_port); if (plat->src_port == 2) wm8350_cpu_dai = imx_ssi_dai[2]; else wm8350_cpu_dai = imx_ssi_dai[0]; imx_3stack_dai.cpu_dai = wm8350_cpu_dai; ret = driver_create_file(pdev->dev.driver, &driver_attr_headphone); if (ret < 0) { pr_err("%s:failed to create driver_attr_headphone\n", __func__); return ret; } /* enable slow clock gen for jack detect */ reg = wm8350_reg_read(wm8350, WM8350_POWER_MGMT_4); wm8350_reg_write(wm8350, WM8350_POWER_MGMT_4, reg | WM8350_TOCLK_ENA); /* enable jack detect */ reg = wm8350_reg_read(wm8350, WM8350_JACK_DETECT); wm8350_reg_write(wm8350, WM8350_JACK_DETECT, reg | WM8350_JDR_ENA); wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R, imx_3stack_jack_handler, NULL); wm8350_unmask_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R); wm8350_jack_func = 1; wm8350_spk_func = 1; return 0; }
static int wm8350_rtc_update_irq_enable(struct device *dev, unsigned int enabled) { struct wm8350 *wm8350 = dev_get_drvdata(dev); /* Suppress duplicate changes since genirq nests enable and * disable calls. */ if (enabled == wm8350->rtc.update_enabled) return 0; if (enabled) wm8350_unmask_irq(wm8350, WM8350_IRQ_RTC_SEC); else wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC); wm8350->rtc.update_enabled = enabled; return 0; }
/** * wm8350_hp_jack_detect - Enable headphone jack detection. * * @codec: WM8350 codec * @which: left or right jack detect signal * @jack: jack to report detection events on * @report: value to report * * Enables the headphone jack detection of the WM8350. */ int wm8350_hp_jack_detect(struct snd_soc_codec *codec, enum wm8350_jack which, struct snd_soc_jack *jack, int report) { struct wm8350_data *priv = codec->private_data; struct wm8350 *wm8350 = codec->control_data; int irq; int ena; switch (which) { case WM8350_JDL: priv->hpl.jack = jack; priv->hpl.report = report; irq = WM8350_IRQ_CODEC_JCK_DET_L; ena = WM8350_JDL_ENA; break; case WM8350_JDR: priv->hpr.jack = jack; priv->hpr.report = report; irq = WM8350_IRQ_CODEC_JCK_DET_R; ena = WM8350_JDR_ENA; break; default: return -EINVAL; } wm8350_set_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_TOCLK_ENA); wm8350_set_bits(wm8350, WM8350_JACK_DETECT, ena); /* Sync status */ wm8350_hp_jack_handler(wm8350, irq, priv); wm8350_unmask_irq(wm8350, irq); return 0; }
/* * Handle commands from user-space */ static int wm8350_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) { struct wm8350 *wm8350 = dev_get_drvdata(dev); switch (cmd) { case RTC_AIE_OFF: return wm8350_rtc_stop_alarm(wm8350); case RTC_AIE_ON: return wm8350_rtc_start_alarm(wm8350); case RTC_UIE_OFF: wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC); break; case RTC_UIE_ON: wm8350_unmask_irq(wm8350, WM8350_IRQ_RTC_SEC); break; default: return -ENOIOCTLCMD; } return 0; }
//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 void wm8350_init_charger(struct wm8350 *wm8350) { wm8350_register_irq(wm8350, WM8350_IRQ_CHG_BAT_HOT, wm8350_charger_handler, NULL); wm8350_unmask_irq(wm8350, WM8350_IRQ_CHG_BAT_HOT); wm8350_register_irq(wm8350, WM8350_IRQ_CHG_BAT_COLD, wm8350_charger_handler, NULL); wm8350_unmask_irq(wm8350, WM8350_IRQ_CHG_BAT_COLD); wm8350_register_irq(wm8350, WM8350_IRQ_CHG_BAT_FAIL, wm8350_charger_handler, NULL); wm8350_unmask_irq(wm8350, WM8350_IRQ_CHG_BAT_FAIL); wm8350_register_irq(wm8350, WM8350_IRQ_CHG_TO, wm8350_charger_handler, NULL); wm8350_unmask_irq(wm8350, WM8350_IRQ_CHG_TO); wm8350_register_irq(wm8350, WM8350_IRQ_CHG_END, wm8350_charger_handler, NULL); wm8350_unmask_irq(wm8350, WM8350_IRQ_CHG_END); wm8350_register_irq(wm8350, WM8350_IRQ_CHG_START, wm8350_charger_handler, NULL); wm8350_unmask_irq(wm8350, WM8350_IRQ_CHG_START); wm8350_register_irq(wm8350, WM8350_IRQ_CHG_FAST_RDY, wm8350_charger_handler, NULL); wm8350_unmask_irq(wm8350, WM8350_IRQ_CHG_FAST_RDY); wm8350_register_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P9, wm8350_charger_handler, NULL); wm8350_unmask_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P9); wm8350_register_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P1, wm8350_charger_handler, NULL); wm8350_unmask_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P1); wm8350_register_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_2P85, wm8350_charger_handler, NULL); wm8350_unmask_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_2P85); wm8350_register_irq(wm8350, WM8350_IRQ_EXT_USB_FB, wm8350_charger_handler, NULL); wm8350_unmask_irq(wm8350, WM8350_IRQ_EXT_USB_FB); wm8350_register_irq(wm8350, WM8350_IRQ_EXT_WALL_FB, wm8350_charger_handler, NULL); wm8350_unmask_irq(wm8350, WM8350_IRQ_EXT_WALL_FB); wm8350_register_irq(wm8350, WM8350_IRQ_EXT_BAT_FB, wm8350_charger_handler, NULL); wm8350_unmask_irq(wm8350, WM8350_IRQ_EXT_BAT_FB); }
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; }
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 = rtc_device_register("wm8350", &pdev->dev, &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_mask_irq(wm8350, WM8350_IRQ_RTC_SEC); wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_PER); wm8350_register_irq(wm8350, WM8350_IRQ_RTC_SEC, wm8350_rtc_update_handler, NULL); wm8350_register_irq(wm8350, WM8350_IRQ_RTC_ALM, wm8350_rtc_alarm_handler, NULL); wm8350_unmask_irq(wm8350, WM8350_IRQ_RTC_ALM); return 0; }