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; }
/* * 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, ®); 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, ®); 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; }
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; }
/** * 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; }
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; }
/** * 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; }
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); }
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, ®); 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; }
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, ®); 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, ®); 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; }
/** * 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 *)®); 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, ®); 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; }