コード例 #1
0
static int inmixer_event (struct snd_soc_dapm_widget *w,
	struct snd_kcontrol *kcontrol, int event)
{
	u16 reg, fakepower;

	reg = wm8400_read(w->codec, WM8400_POWER_MANAGEMENT_2);
	fakepower = wm8400_read(w->codec, WM8400_INTDRIVBITS);

	if (fakepower & ((1 << WM8400_INMIXL_PWR) |
		(1 << WM8400_AINLMUX_PWR))) {
		reg |= WM8400_AINL_ENA;
	} else {
		reg &= ~WM8400_AINL_ENA;
	}

	if (fakepower & ((1 << WM8400_INMIXR_PWR) |
		(1 << WM8400_AINRMUX_PWR))) {
		reg |= WM8400_AINR_ENA;
	} else {
		reg &= ~WM8400_AINR_ENA;
	}
	wm8400_write(w->codec, WM8400_POWER_MANAGEMENT_2, reg);

	return 0;
}
コード例 #2
0
ファイル: wm8400-core.c プロジェクト: E-LLP/n900
/*
 * wm8400_init - Generic initialisation
 *
 * The WM8400 can be configured as either an I2C or SPI device.  Probe
 * functions for each bus set up the accessors then call into this to
 * set up the device itself.
 */
static int wm8400_init(struct wm8400 *wm8400,
		       struct wm8400_platform_data *pdata)
{
	u16 reg;
	int ret, i;

	mutex_init(&wm8400->io_lock);

	wm8400->dev->driver_data = wm8400;

	/* Check that this is actually a WM8400 */
	ret = wm8400->read_dev(wm8400->io_data, WM8400_RESET_ID, 1, &reg);
	if (ret != 0) {
		dev_err(wm8400->dev, "Chip ID register read failed\n");
		return -EIO;
	}
	if (be16_to_cpu(reg) != reg_data[WM8400_RESET_ID].default_val) {
		dev_err(wm8400->dev, "Device is not a WM8400, ID is %x\n",
			be16_to_cpu(reg));
		return -ENODEV;
	}

	/* We don't know what state the hardware is in and since this
	 * is a PMIC we can't reset it safely so initialise the register
	 * cache from the hardware.
	 */
	ret = wm8400->read_dev(wm8400->io_data, 0,
			       ARRAY_SIZE(wm8400->reg_cache),
			       wm8400->reg_cache);
	if (ret != 0) {
		dev_err(wm8400->dev, "Register cache read failed\n");
		return -EIO;
	}
	for (i = 0; i < ARRAY_SIZE(wm8400->reg_cache); i++)
		wm8400->reg_cache[i] = be16_to_cpu(wm8400->reg_cache[i]);

	/* If the codec is in reset use hard coded values */
	if (!(wm8400->reg_cache[WM8400_POWER_MANAGEMENT_1] & WM8400_CODEC_ENA))
		for (i = 0; i < ARRAY_SIZE(wm8400->reg_cache); i++)
			if (reg_data[i].is_codec)
				wm8400->reg_cache[i] = reg_data[i].default_val;

	ret = wm8400_read(wm8400, WM8400_ID, 1, &reg);
	if (ret != 0) {
		dev_err(wm8400->dev, "ID register read failed: %d\n", ret);
		return ret;
	}
	reg = (reg & WM8400_CHIP_REV_MASK) >> WM8400_CHIP_REV_SHIFT;
	dev_info(wm8400->dev, "WM8400 revision %x\n", reg);

	if (pdata && pdata->platform_init) {
		ret = pdata->platform_init(wm8400->dev);
		if (ret != 0)
			dev_err(wm8400->dev, "Platform init failed: %d\n",
				ret);
	} else
		dev_warn(wm8400->dev, "No platform initialisation supplied\n");

	return ret;
}
コード例 #3
0
static int outmixer_event (struct snd_soc_dapm_widget *w,
	struct snd_kcontrol * kcontrol, int event)
{
	struct soc_mixer_control *mc =
		(struct soc_mixer_control *)kcontrol->private_value;
	u32 reg_shift = mc->shift;
	int ret = 0;
	u16 reg;

	switch (reg_shift) {
	case WM8400_SPEAKER_MIXER | (WM8400_LDSPK << 8) :
		reg = wm8400_read(w->codec, WM8400_OUTPUT_MIXER1);
		if (reg & WM8400_LDLO) {
			printk(KERN_WARNING
			"Cannot set as Output Mixer 1 LDLO Set\n");
			ret = -1;
		}
		break;
	case WM8400_SPEAKER_MIXER | (WM8400_RDSPK << 8):
		reg = wm8400_read(w->codec, WM8400_OUTPUT_MIXER2);
		if (reg & WM8400_RDRO) {
			printk(KERN_WARNING
			"Cannot set as Output Mixer 2 RDRO Set\n");
			ret = -1;
		}
		break;
	case WM8400_OUTPUT_MIXER1 | (WM8400_LDLO << 8):
		reg = wm8400_read(w->codec, WM8400_SPEAKER_MIXER);
		if (reg & WM8400_LDSPK) {
			printk(KERN_WARNING
			"Cannot set as Speaker Mixer LDSPK Set\n");
			ret = -1;
		}
		break;
	case WM8400_OUTPUT_MIXER2 | (WM8400_RDRO << 8):
		reg = wm8400_read(w->codec, WM8400_SPEAKER_MIXER);
		if (reg & WM8400_RDSPK) {
			printk(KERN_WARNING
			"Cannot set as Speaker Mixer RDSPK Set\n");
			ret = -1;
		}
		break;
	}

	return ret;
}
コード例 #4
0
/**
 * wm8400_reg_read - Single register read
 *
 * @wm8400: Pointer to wm8400 control structure
 * @reg:    Register to read
 *
 * @return  Read value
 */
u16 wm8400_reg_read(struct wm8400 *wm8400, u8 reg)
{
	u16 val;

	mutex_lock(&wm8400->io_lock);
	wm8400_read(wm8400, reg, 1, &val);
	mutex_unlock(&wm8400->io_lock);

	return val;
}
コード例 #5
0
ファイル: wm8400-core.c プロジェクト: JackWangCUMT/linux
int wm8400_block_read(struct wm8400 *wm8400, u8 reg, int count, u16 *data)
{
    int ret;

    mutex_lock(&wm8400->io_lock);

    ret = wm8400_read(wm8400, reg, count, data);

    mutex_unlock(&wm8400->io_lock);

    return ret;
}
コード例 #6
0
ファイル: wm8400-core.c プロジェクト: JackWangCUMT/linux
/**
 * wm8400_set_bits - Bitmask write
 *
 * @wm8400: Pointer to wm8400 control structure
 * @reg:    Register to access
 * @mask:   Mask of bits to change
 * @val:    Value to set for masked bits
 */
int wm8400_set_bits(struct wm8400 *wm8400, u8 reg, u16 mask, u16 val)
{
    u16 tmp;
    int ret;

    mutex_lock(&wm8400->io_lock);

    ret = wm8400_read(wm8400, reg, 1, &tmp);
    tmp = (tmp & ~mask) | val;
    if (ret == 0)
        ret = wm8400_write(wm8400, reg, 1, &tmp);

    mutex_unlock(&wm8400->io_lock);

    return ret;
}
コード例 #7
0
static int wm8400_outpga_put_volsw_vu(struct snd_kcontrol *kcontrol,
        struct snd_ctl_elem_value *ucontrol)
{
        struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
	struct soc_mixer_control *mc =
		(struct soc_mixer_control *)kcontrol->private_value;
	int reg = mc->reg;
        int ret;
        u16 val;

        ret = snd_soc_put_volsw(kcontrol, ucontrol);
        if (ret < 0)
                return ret;

        /*                                               */
        val = wm8400_read(codec, reg);
        return wm8400_write(codec, reg, val | 0x0100);
}
コード例 #8
0
ファイル: wm8400-core.c プロジェクト: JackWangCUMT/linux
static int wm8400_register_codec(struct wm8400 *wm8400)
{
    struct mfd_cell cell = {
        .name = "wm8400-codec",
        .platform_data = wm8400,
        .pdata_size = sizeof(*wm8400),
    };

    return mfd_add_devices(wm8400->dev, -1, &cell, 1, NULL, 0);
}

/*
 * wm8400_init - Generic initialisation
 *
 * The WM8400 can be configured as either an I2C or SPI device.  Probe
 * functions for each bus set up the accessors then call into this to
 * set up the device itself.
 */
static int wm8400_init(struct wm8400 *wm8400,
                       struct wm8400_platform_data *pdata)
{
    u16 reg;
    int ret, i;

    mutex_init(&wm8400->io_lock);

    dev_set_drvdata(wm8400->dev, wm8400);

    /* Check that this is actually a WM8400 */
    ret = regmap_read(wm8400->regmap, WM8400_RESET_ID, &i);
    if (ret != 0) {
        dev_err(wm8400->dev, "Chip ID register read failed\n");
        return -EIO;
    }
    if (i != reg_data[WM8400_RESET_ID].default_val) {
        dev_err(wm8400->dev, "Device is not a WM8400, ID is %x\n",
                reg);
        return -ENODEV;
    }

    /* We don't know what state the hardware is in and since this
     * is a PMIC we can't reset it safely so initialise the register
     * cache from the hardware.
     */
    ret = regmap_raw_read(wm8400->regmap, 0, wm8400->reg_cache,
                          ARRAY_SIZE(wm8400->reg_cache));
    if (ret != 0) {
        dev_err(wm8400->dev, "Register cache read failed\n");
        return -EIO;
    }
    for (i = 0; i < ARRAY_SIZE(wm8400->reg_cache); i++)
        wm8400->reg_cache[i] = be16_to_cpu(wm8400->reg_cache[i]);

    /* If the codec is in reset use hard coded values */
    if (!(wm8400->reg_cache[WM8400_POWER_MANAGEMENT_1] & WM8400_CODEC_ENA))
        for (i = 0; i < ARRAY_SIZE(wm8400->reg_cache); i++)
            if (reg_data[i].is_codec)
                wm8400->reg_cache[i] = reg_data[i].default_val;

    ret = wm8400_read(wm8400, WM8400_ID, 1, &reg);
    if (ret != 0) {
        dev_err(wm8400->dev, "ID register read failed: %d\n", ret);
        return ret;
    }
    reg = (reg & WM8400_CHIP_REV_MASK) >> WM8400_CHIP_REV_SHIFT;
    dev_info(wm8400->dev, "WM8400 revision %x\n", reg);

    ret = wm8400_register_codec(wm8400);
    if (ret != 0) {
        dev_err(wm8400->dev, "Failed to register codec\n");
        goto err_children;
    }

    if (pdata && pdata->platform_init) {
        ret = pdata->platform_init(wm8400->dev);
        if (ret != 0) {
            dev_err(wm8400->dev, "Platform init failed: %d\n",
                    ret);
            goto err_children;
        }
    } else
        dev_warn(wm8400->dev, "No platform initialisation supplied\n");

    return 0;

err_children:
    mfd_remove_devices(wm8400->dev);
    return ret;
}
コード例 #9
0
static int wm8400_register_codec(struct wm8400 *wm8400)
{
	struct mfd_cell cell = {
		.name = "wm8400-codec",
		.driver_data = wm8400,
	};

	return mfd_add_devices(wm8400->dev, -1, &cell, 1, NULL, 0);
}


static int wm8400_init(struct wm8400 *wm8400,
		       struct wm8400_platform_data *pdata)
{
	u16 reg;
	int ret, i;

	mutex_init(&wm8400->io_lock);

	dev_set_drvdata(wm8400->dev, wm8400);

	
	ret = wm8400->read_dev(wm8400->io_data, WM8400_RESET_ID, 1, &reg);
	if (ret != 0) {
		dev_err(wm8400->dev, "Chip ID register read failed\n");
		return -EIO;
	}
	if (be16_to_cpu(reg) != reg_data[WM8400_RESET_ID].default_val) {
		dev_err(wm8400->dev, "Device is not a WM8400, ID is %x\n",
			be16_to_cpu(reg));
		return -ENODEV;
	}

	
	ret = wm8400->read_dev(wm8400->io_data, 0,
			       ARRAY_SIZE(wm8400->reg_cache),
			       wm8400->reg_cache);
	if (ret != 0) {
		dev_err(wm8400->dev, "Register cache read failed\n");
		return -EIO;
	}
	for (i = 0; i < ARRAY_SIZE(wm8400->reg_cache); i++)
		wm8400->reg_cache[i] = be16_to_cpu(wm8400->reg_cache[i]);

	
	if (!(wm8400->reg_cache[WM8400_POWER_MANAGEMENT_1] & WM8400_CODEC_ENA))
		for (i = 0; i < ARRAY_SIZE(wm8400->reg_cache); i++)
			if (reg_data[i].is_codec)
				wm8400->reg_cache[i] = reg_data[i].default_val;

	ret = wm8400_read(wm8400, WM8400_ID, 1, &reg);
	if (ret != 0) {
		dev_err(wm8400->dev, "ID register read failed: %d\n", ret);
		return ret;
	}
	reg = (reg & WM8400_CHIP_REV_MASK) >> WM8400_CHIP_REV_SHIFT;
	dev_info(wm8400->dev, "WM8400 revision %x\n", reg);

	ret = wm8400_register_codec(wm8400);
	if (ret != 0) {
		dev_err(wm8400->dev, "Failed to register codec\n");
		goto err_children;
	}

	if (pdata && pdata->platform_init) {
		ret = pdata->platform_init(wm8400->dev);
		if (ret != 0) {
			dev_err(wm8400->dev, "Platform init failed: %d\n",
				ret);
			goto err_children;
		}
	} else
		dev_warn(wm8400->dev, "No platform initialisation supplied\n");

	return 0;

err_children:
	mfd_remove_devices(wm8400->dev);
	return ret;
}
コード例 #10
0
/**
 * wm8400_init - Initialisation of the driver
 *
 * The WM8400 supports both I2C and SPI control.  This function, which must
 * be called prior to any other WM8400 bus operation, is
 */
int wm8400_init(struct wm8400 *wm8400, int io,
		int (*read_dev)(struct wm8400 *wm8400, char reg, int size,
				char *dest),
		int (*write_dev)(struct wm8400 *wm8400, char reg, int size,
				 const char *src))
{
	u16 reg;
	int ret, i;

	mutex_init(&wm8400->io_lock);

	switch (io) {
#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
	case WM8400_IO_I2C:
		wm8400->read_dev = wm8400_read_i2c_device;
		wm8400->write_dev = wm8400_write_i2c_device;
		wm8400->dev = &wm8400->i2c_client->dev;
		break;
#endif
#if defined(CONFIG_SPI) || defined(CONFIG_SPI_MODULE)
	case WM8400_IO_SPI:
		wm8400->read_dev = wm8400_read_spi_device;
		wm8400->write_dev = wm8400_write_spi_device;
		wm8400->dev = &wm8400->spi_client->dev;
		break;
#endif
	case WM8400_IO_CUSTOM:
		wm8400->read_dev = read_dev;
		wm8400->write_dev = write_dev;
		break;
	default:
		printk(KERN_ERR "wm8400: Unknown I/O mechansim %d selected\n",
		       io);
		wm8400->read_dev = NULL;
		wm8400->write_dev = NULL;
		return -EINVAL;
	}

	/* Check that this is actually a WM8400 */
	ret = wm8400->read_dev(wm8400, WM8400_RESET_ID, 2, (char *)&reg);
	if (ret != 2) {
		dev_err(wm8400->dev, "Chip ID register read failed\n");
		return -EIO;
	}
	if (be16_to_cpu(reg) != 0x6172) {
		dev_err(wm8400->dev, "Device is not a WM8400\n");
		return -ENODEV;
	}

	/* We don't know what state the hardware is in and since this
	 * is a PMIC we can't reset it.
	 */
	ret = wm8400->read_dev(wm8400, 0, sizeof(wm8400->reg_cache),
			       (char *)&wm8400->reg_cache);
	if (ret != sizeof(wm8400->reg_cache)) {
		dev_err(wm8400->dev, "Register cache read failed\n");
		return -EIO;
	}
	for (i = 0; i < ARRAY_SIZE(wm8400->reg_cache); i++) {
		wm8400->reg_cache[i] = be16_to_cpu(wm8400->reg_cache[i]);
	}

	/* If the codec is in reset use hard coded values */
	if (!(wm8400->reg_cache[WM8400_POWER_MANAGEMENT_1] & WM8400_CODEC_ENA))
		for (i = 0; i < ARRAY_SIZE(wm8400->reg_cache); i++)
			if (reg_data[i].is_codec)
				wm8400->reg_cache[i] = reg_data[i].default_val;

	ret = wm8400_read(wm8400, WM8400_ID, 1, &reg);
	if (ret != 0) {
		dev_err(wm8400->dev, "ID register read failed: %d\n", ret);
		return ret;
	}
	reg = (reg & WM8400_CHIP_REV_MASK) >> WM8400_CHIP_REV_SHIFT;
	dev_info(wm8400->dev, "WM8400 revision %x\n", reg);

	/* We've got the chip, now register client devices */
	ret = wm8400_register_device(wm8400, &wm8400->regulator.dev,
				     "wm8400-regulator");

	ret = wm8400_register_device(wm8400, &wm8400->codec,
				     "wm8400-codec");

	return 0;
}