void wm8350_free(struct wm8350 *wm8350)
{
#if BATTERY
    struct wm8350_power *power = &wm8350->power;
#endif

    wm8350_mask_irq(wm8350, WM8350_IRQ_GPIO(7));
    wm8350_free_irq(wm8350, WM8350_IRQ_GPIO(7));
    wm8350_mask_irq(wm8350, WM8350_IRQ_WKUP_ONKEY);
    wm8350_free_irq(wm8350, WM8350_IRQ_WKUP_ONKEY);

#if BATTERY
    wm8350_charger_enable(power, 0);
    wm8350_fast_charger_enable(power, 0);
#endif
    if (wm8350->nirq)
        free_irq(wm8350->nirq, wm8350);

    flush_scheduled_work();

    if (wm8350->pmic.dev.is_registered)
        device_unregister(&wm8350->pmic.dev);
    if (wm8350->rtc.dev.is_registered)
        device_unregister(&wm8350->rtc.dev);
    if (wm8350->wdg.dev.is_registered)
        device_unregister(&wm8350->wdg.dev);
    if (wm8350->power.dev.is_registered)
        device_unregister(&wm8350->power.dev);

    platform_device_unregister(imx_snd_device);
}
Пример #2
0
/*
 * 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;
}
Пример #3
0
static int imx_3stack_wm8350_remove(struct platform_device *pdev)
{
	struct imx_3stack_priv *priv = &machine_priv;
	struct wm8350 *wm8350 = priv->wm8350;

	wm8350_mask_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R);
	wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R);

	return 0;
}
Пример #4
0
static int wm8350_regulator_remove(struct platform_device *pdev)
{
	struct regulator_dev *rdev = platform_get_drvdata(pdev);
	struct wm8350 *wm8350 = rdev_get_drvdata(rdev);

	wm8350_mask_irq(wm8350, wm8350_reg[pdev->id].irq);
	wm8350_free_irq(wm8350, wm8350_reg[pdev->id].irq);

	regulator_unregister(rdev);

	return 0;
}
Пример #5
0
static int __exit wm8350_rtc_remove(struct platform_device *pdev)
{
	struct wm8350 *wm8350 = platform_get_drvdata(pdev);
	struct wm8350_rtc *wm_rtc = &wm8350->rtc;
	int ret;

	if (wm_rtc->per_irq)
		free_irq(wm_rtc->per_irq, wm8350);
	wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC);
	wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_ALM);
	wm8350_free_irq(wm8350, WM8350_IRQ_RTC_SEC);
	wm8350_free_irq(wm8350, WM8350_IRQ_RTC_ALM);
	rtc_device_unregister(wm_rtc->rtc);

	ret = wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5,
				WM8350_RTC_TICK_ENA);
	if (ret < 0)
		printk(KERN_ERR "wm8350-rtc: failed to enable RTC\n");

	return 0;
}
Пример #6
0
static void wm8350_irq_call_handler(struct wm8350 *wm8350, int irq)
{
	mutex_lock(&wm8350->irq_mutex);

	if (wm8350->irq[irq].handler)
		wm8350->irq[irq].handler(wm8350, irq, wm8350->irq[irq].data);
	else {
		dev_err(wm8350->dev, "irq %d nobody cared. now masked.\n",
			irq);
		wm8350_mask_irq(wm8350, irq);
	}

	mutex_unlock(&wm8350->irq_mutex);
}
Пример #7
0
static int __devexit wm8350_rtc_remove(struct platform_device *pdev)
{
	struct wm8350 *wm8350 = platform_get_drvdata(pdev);
	struct wm8350_rtc *wm_rtc = &wm8350->rtc;

	wm8350_mask_irq(wm8350, WM8350_IRQ_RTC_SEC);

	wm8350_free_irq(wm8350, WM8350_IRQ_RTC_SEC);
	wm8350_free_irq(wm8350, WM8350_IRQ_RTC_ALM);

	rtc_device_unregister(wm_rtc->rtc);

	return 0;
}
Пример #8
0
static int wm8350_remove(struct platform_device *pdev)
{
	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
	struct snd_soc_codec *codec = socdev->card->codec;
	struct wm8350 *wm8350 = codec->control_data;
	struct wm8350_data *priv = codec->private_data;
	int ret;

	wm8350_clear_bits(wm8350, WM8350_JACK_DETECT,
			  WM8350_JDL_ENA | WM8350_JDR_ENA);
	wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_4, WM8350_TOCLK_ENA);

	wm8350_mask_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L);
	wm8350_mask_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R);
	wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L);
	wm8350_free_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R);

	priv->hpl.jack = NULL;
	priv->hpr.jack = NULL;

	/* cancel any work waiting to be queued. */
	ret = cancel_delayed_work(&codec->delayed_work);

	/* if there was any work waiting then we run it now and
	 * wait for its completion */
	if (ret) {
		schedule_delayed_work(&codec->delayed_work, 0);
		flush_scheduled_work();
	}

	wm8350_set_bias_level(codec, SND_SOC_BIAS_OFF);

	wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);

	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;
}
Пример #10
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;
}
Пример #11
0
static void free_charger_irq(struct wm8350 *wm8350)
{
	wm8350_mask_irq(wm8350, WM8350_IRQ_CHG_BAT_HOT);
	wm8350_free_irq(wm8350, WM8350_IRQ_CHG_BAT_HOT);
	wm8350_mask_irq(wm8350, WM8350_IRQ_CHG_BAT_COLD);
	wm8350_free_irq(wm8350, WM8350_IRQ_CHG_BAT_COLD);
	wm8350_mask_irq(wm8350, WM8350_IRQ_CHG_BAT_FAIL);
	wm8350_free_irq(wm8350, WM8350_IRQ_CHG_BAT_FAIL);
	wm8350_mask_irq(wm8350, WM8350_IRQ_CHG_TO);
	wm8350_free_irq(wm8350, WM8350_IRQ_CHG_TO);
	wm8350_mask_irq(wm8350, WM8350_IRQ_CHG_END);
	wm8350_free_irq(wm8350, WM8350_IRQ_CHG_END);
	wm8350_mask_irq(wm8350, WM8350_IRQ_CHG_START);
	wm8350_free_irq(wm8350, WM8350_IRQ_CHG_START);
	wm8350_mask_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P9);
	wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P9);
	wm8350_mask_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P1);
	wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_3P1);
	wm8350_mask_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_2P85);
	wm8350_free_irq(wm8350, WM8350_IRQ_CHG_VBATT_LT_2P85);
	wm8350_mask_irq(wm8350, WM8350_IRQ_EXT_USB_FB);
	wm8350_free_irq(wm8350, WM8350_IRQ_EXT_USB_FB);
	wm8350_mask_irq(wm8350, WM8350_IRQ_EXT_WALL_FB);
	wm8350_free_irq(wm8350, WM8350_IRQ_EXT_WALL_FB);
	wm8350_mask_irq(wm8350, WM8350_IRQ_EXT_BAT_FB);
	wm8350_free_irq(wm8350, WM8350_IRQ_EXT_BAT_FB);
}
Пример #12
0
static void imx_3stack_jack_handler(struct wm8350 *wm8350, int irq, void *data)
{
	wm8350_mask_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R);
	schedule_delayed_work(&hp_event, msecs_to_jiffies(200));
}
Пример #13
0
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;
}
Пример #14
0
static int wm8350_probe(struct platform_device *pdev)
{
	struct snd_soc_device *socdev = platform_get_drvdata(pdev);
	struct snd_soc_codec *codec;
	struct wm8350 *wm8350;
	struct wm8350_data *priv;
	int ret;
	struct wm8350_output *out1;
	struct wm8350_output *out2;

	BUG_ON(!wm8350_codec);

	socdev->card->codec = wm8350_codec;
	codec = socdev->card->codec;
	wm8350 = codec->control_data;
	priv = codec->private_data;

	/* Enable the codec */
	wm8350_set_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA);

	/* Enable robust clocking mode in ADC */
	wm8350_codec_write(codec, WM8350_SECURITY, 0xa7);
	wm8350_codec_write(codec, 0xde, 0x13);
	wm8350_codec_write(codec, WM8350_SECURITY, 0);

	/* read OUT1 & OUT2 volumes */
	out1 = &priv->out1;
	out2 = &priv->out2;
	out1->left_vol = (wm8350_reg_read(wm8350, WM8350_LOUT1_VOLUME) &
			  WM8350_OUT1L_VOL_MASK) >> WM8350_OUT1L_VOL_SHIFT;
	out1->right_vol = (wm8350_reg_read(wm8350, WM8350_ROUT1_VOLUME) &
			   WM8350_OUT1R_VOL_MASK) >> WM8350_OUT1R_VOL_SHIFT;
	out2->left_vol = (wm8350_reg_read(wm8350, WM8350_LOUT2_VOLUME) &
			  WM8350_OUT2L_VOL_MASK) >> WM8350_OUT1L_VOL_SHIFT;
	out2->right_vol = (wm8350_reg_read(wm8350, WM8350_ROUT2_VOLUME) &
			   WM8350_OUT2R_VOL_MASK) >> WM8350_OUT1R_VOL_SHIFT;
	wm8350_reg_write(wm8350, WM8350_LOUT1_VOLUME, 0);
	wm8350_reg_write(wm8350, WM8350_ROUT1_VOLUME, 0);
	wm8350_reg_write(wm8350, WM8350_LOUT2_VOLUME, 0);
	wm8350_reg_write(wm8350, WM8350_ROUT2_VOLUME, 0);

	/* Latch VU bits & mute */
	wm8350_set_bits(wm8350, WM8350_LOUT1_VOLUME,
			WM8350_OUT1_VU | WM8350_OUT1L_MUTE);
	wm8350_set_bits(wm8350, WM8350_LOUT2_VOLUME,
			WM8350_OUT2_VU | WM8350_OUT2L_MUTE);
	wm8350_set_bits(wm8350, WM8350_ROUT1_VOLUME,
			WM8350_OUT1_VU | WM8350_OUT1R_MUTE);
	wm8350_set_bits(wm8350, WM8350_ROUT2_VOLUME,
			WM8350_OUT2_VU | WM8350_OUT2R_MUTE);

	wm8350_mask_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L);
	wm8350_mask_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R);
	wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_L,
			    wm8350_hp_jack_handler, priv);
	wm8350_register_irq(wm8350, WM8350_IRQ_CODEC_JCK_DET_R,
			    wm8350_hp_jack_handler, priv);

	ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
	if (ret < 0) {
		dev_err(&pdev->dev, "failed to create pcms\n");
		return ret;
	}

	snd_soc_add_controls(codec, wm8350_snd_controls,
				ARRAY_SIZE(wm8350_snd_controls));
	wm8350_add_widgets(codec);

	wm8350_set_bias_level(codec, SND_SOC_BIAS_STANDBY);

	return 0;
}