cregit-Linux how code gets into the kernel

Release 4.7 sound/soc/codecs/pcm179x.c

Directory: sound/soc/codecs
/*
 * PCM179X ASoC codec driver
 *
 * Copyright (c) Amarula Solutions B.V. 2013
 *
 *     Michael Trimarchi <michael@amarulasolutions.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/module.h>
#include <linux/slab.h>
#include <linux/kernel.h>
#include <linux/device.h>

#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/initval.h>
#include <sound/soc.h>
#include <sound/tlv.h>
#include <linux/of.h>

#include "pcm179x.h"


#define PCM179X_DAC_VOL_LEFT	0x10

#define PCM179X_DAC_VOL_RIGHT	0x11

#define PCM179X_FMT_CONTROL	0x12

#define PCM179X_MODE_CONTROL	0x13

#define PCM179X_SOFT_MUTE	PCM179X_FMT_CONTROL


#define PCM179X_FMT_MASK	0x70

#define PCM179X_FMT_SHIFT	4

#define PCM179X_MUTE_MASK	0x01

#define PCM179X_MUTE_SHIFT	0

#define PCM179X_ATLD_ENABLE	(1 << 7)


static const struct reg_default pcm179x_reg_defaults[] = {
	{ 0x10, 0xff },
	{ 0x11, 0xff },
	{ 0x12, 0x50 },
	{ 0x13, 0x00 },
	{ 0x14, 0x00 },
	{ 0x15, 0x01 },
	{ 0x16, 0x00 },
	{ 0x17, 0x00 },
};


static bool pcm179x_accessible_reg(struct device *dev, unsigned int reg) { return reg >= 0x10 && reg <= 0x17; }

Contributors

PersonTokensPropCommitsCommitProp
michael trimarchimichael trimarchi24100.00%2100.00%
Total24100.00%2100.00%


static bool pcm179x_writeable_reg(struct device *dev, unsigned register reg) { bool accessible; accessible = pcm179x_accessible_reg(dev, reg); return accessible && reg != 0x16 && reg != 0x17; }

Contributors

PersonTokensPropCommitsCommitProp
michael trimarchimichael trimarchi38100.00%2100.00%
Total38100.00%2100.00%

struct pcm179x_private { struct regmap *regmap; unsigned int format; unsigned int rate; };
static int pcm179x_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int format) { struct snd_soc_codec *codec = codec_dai->codec; struct pcm179x_private *priv = snd_soc_codec_get_drvdata(codec); priv->format = format; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
michael trimarchimichael trimarchi43100.00%2100.00%
Total43100.00%2100.00%


static int pcm179x_digital_mute(struct snd_soc_dai *dai, int mute) { struct snd_soc_codec *codec = dai->codec; struct pcm179x_private *priv = snd_soc_codec_get_drvdata(codec); int ret; ret = regmap_update_bits(priv->regmap, PCM179X_SOFT_MUTE, PCM179X_MUTE_MASK, !!mute); if (ret < 0) return ret; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
michael trimarchimichael trimarchi65100.00%2100.00%
Total65100.00%2100.00%


static int pcm179x_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { struct snd_soc_codec *codec = dai->codec; struct pcm179x_private *priv = snd_soc_codec_get_drvdata(codec); int val = 0, ret; priv->rate = params_rate(params); switch (priv->format & SND_SOC_DAIFMT_FORMAT_MASK) { case SND_SOC_DAIFMT_RIGHT_J: switch (params_width(params)) { case 24: case 32: val = 2; break; case 16: val = 0; break; default: return -EINVAL; } break; case SND_SOC_DAIFMT_I2S: switch (params_width(params)) { case 24: case 32: val = 5; break; case 16: val = 4; break; default: return -EINVAL; } break; default: dev_err(codec->dev, "Invalid DAI format\n"); return -EINVAL; } val = val << PCM179X_FMT_SHIFT | PCM179X_ATLD_ENABLE; ret = regmap_update_bits(priv->regmap, PCM179X_FMT_CONTROL, PCM179X_FMT_MASK | PCM179X_ATLD_ENABLE, val); if (ret < 0) return ret; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
michael trimarchimichael trimarchi14173.82%266.67%
mark brownmark brown5026.18%133.33%
Total191100.00%3100.00%

static const struct snd_soc_dai_ops pcm179x_dai_ops = { .set_fmt = pcm179x_set_dai_fmt, .hw_params = pcm179x_hw_params, .digital_mute = pcm179x_digital_mute, }; static const DECLARE_TLV_DB_SCALE(pcm179x_dac_tlv, -12000, 50, 1); static const struct snd_kcontrol_new pcm179x_controls[] = { SOC_DOUBLE_R_RANGE_TLV("DAC Playback Volume", PCM179X_DAC_VOL_LEFT, PCM179X_DAC_VOL_RIGHT, 0, 0xf, 0xff, 0, pcm179x_dac_tlv), SOC_SINGLE("DAC Invert Output Switch", PCM179X_MODE_CONTROL, 7, 1, 0), SOC_SINGLE("DAC Rolloff Filter Switch", PCM179X_MODE_CONTROL, 1, 1, 0), }; static const struct snd_soc_dapm_widget pcm179x_dapm_widgets[] = { SND_SOC_DAPM_OUTPUT("IOUTL+"), SND_SOC_DAPM_OUTPUT("IOUTL-"), SND_SOC_DAPM_OUTPUT("IOUTR+"), SND_SOC_DAPM_OUTPUT("IOUTR-"), }; static const struct snd_soc_dapm_route pcm179x_dapm_routes[] = { { "IOUTL+", NULL, "Playback" }, { "IOUTL-", NULL, "Playback" }, { "IOUTR+", NULL, "Playback" }, { "IOUTR-", NULL, "Playback" }, }; static struct snd_soc_dai_driver pcm179x_dai = { .name = "pcm179x-hifi", .playback = { .stream_name = "Playback", .channels_min = 2, .channels_max = 2, .rates = SNDRV_PCM_RATE_CONTINUOUS, .rate_min = 10000, .rate_max = 200000, .formats = PCM1792A_FORMATS, }, .ops = &pcm179x_dai_ops, }; const struct regmap_config pcm179x_regmap_config = { .reg_bits = 8, .val_bits = 8, .max_register = 23, .reg_defaults = pcm179x_reg_defaults, .num_reg_defaults = ARRAY_SIZE(pcm179x_reg_defaults), .writeable_reg = pcm179x_writeable_reg, .readable_reg = pcm179x_accessible_reg, }; EXPORT_SYMBOL_GPL(pcm179x_regmap_config); static struct snd_soc_codec_driver soc_codec_dev_pcm179x = { .controls = pcm179x_controls, .num_controls = ARRAY_SIZE(pcm179x_controls), .dapm_widgets = pcm179x_dapm_widgets, .num_dapm_widgets = ARRAY_SIZE(pcm179x_dapm_widgets), .dapm_routes = pcm179x_dapm_routes, .num_dapm_routes = ARRAY_SIZE(pcm179x_dapm_routes), };
int pcm179x_common_init(struct device *dev, struct regmap *regmap) { struct pcm179x_private *pcm179x; pcm179x = devm_kzalloc(dev, sizeof(struct pcm179x_private), GFP_KERNEL); if (!pcm179x) return -ENOMEM; pcm179x->regmap = regmap; dev_set_drvdata(dev, pcm179x); return snd_soc_register_codec(dev, &soc_codec_dev_pcm179x, &pcm179x_dai, 1); }

Contributors

PersonTokensPropCommitsCommitProp
michael trimarchimichael trimarchi6185.92%266.67%
jacob siverskogjacob siverskog1014.08%133.33%
Total71100.00%3100.00%

EXPORT_SYMBOL_GPL(pcm179x_common_init);
int pcm179x_common_exit(struct device *dev) { snd_soc_unregister_codec(dev); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
michael trimarchimichael trimarchi1583.33%150.00%
jacob siverskogjacob siverskog316.67%150.00%
Total18100.00%2100.00%

EXPORT_SYMBOL_GPL(pcm179x_common_exit); MODULE_DESCRIPTION("ASoC PCM179X driver"); MODULE_AUTHOR("Michael Trimarchi <michael@amarulasolutions.com>"); MODULE_LICENSE("GPL");

Overall Contributors

PersonTokensPropCommitsCommitProp
michael trimarchimichael trimarchi76180.79%333.33%
mark brownmark brown14014.86%222.22%
jacob siverskogjacob siverskog373.93%222.22%
sachin kamatsachin kamat30.32%111.11%
axel linaxel lin10.11%111.11%
Total942100.00%9100.00%
Directory: sound/soc/codecs
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
{% endraw %}