root/drivers/media/i2c/wm8739.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. to_state
  2. to_sd
  3. wm8739_write
  4. wm8739_s_ctrl
  5. wm8739_s_clock_freq
  6. wm8739_log_status
  7. wm8739_probe
  8. wm8739_remove

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * wm8739
   4  *
   5  * Copyright (C) 2005 T. Adachi <tadachi@tadachi-net.com>
   6  *
   7  * Copyright (C) 2005 Hans Verkuil <hverkuil@xs4all.nl>
   8  * - Cleanup
   9  */
  10 
  11 #include <linux/module.h>
  12 #include <linux/types.h>
  13 #include <linux/slab.h>
  14 #include <linux/ioctl.h>
  15 #include <linux/uaccess.h>
  16 #include <linux/i2c.h>
  17 #include <linux/videodev2.h>
  18 #include <media/v4l2-device.h>
  19 #include <media/v4l2-ctrls.h>
  20 
  21 MODULE_DESCRIPTION("wm8739 driver");
  22 MODULE_AUTHOR("T. Adachi, Hans Verkuil");
  23 MODULE_LICENSE("GPL");
  24 
  25 static int debug;
  26 
  27 module_param(debug, int, 0644);
  28 
  29 MODULE_PARM_DESC(debug, "Debug level (0-1)");
  30 
  31 
  32 /* ------------------------------------------------------------------------ */
  33 
  34 enum {
  35         R0 = 0, R1,
  36         R5 = 5, R6, R7, R8, R9, R15 = 15,
  37         TOT_REGS
  38 };
  39 
  40 struct wm8739_state {
  41         struct v4l2_subdev sd;
  42         struct v4l2_ctrl_handler hdl;
  43         struct {
  44                 /* audio cluster */
  45                 struct v4l2_ctrl *volume;
  46                 struct v4l2_ctrl *mute;
  47                 struct v4l2_ctrl *balance;
  48         };
  49         u32 clock_freq;
  50 };
  51 
  52 static inline struct wm8739_state *to_state(struct v4l2_subdev *sd)
  53 {
  54         return container_of(sd, struct wm8739_state, sd);
  55 }
  56 
  57 static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
  58 {
  59         return &container_of(ctrl->handler, struct wm8739_state, hdl)->sd;
  60 }
  61 
  62 /* ------------------------------------------------------------------------ */
  63 
  64 static int wm8739_write(struct v4l2_subdev *sd, int reg, u16 val)
  65 {
  66         struct i2c_client *client = v4l2_get_subdevdata(sd);
  67         int i;
  68 
  69         if (reg < 0 || reg >= TOT_REGS) {
  70                 v4l2_err(sd, "Invalid register R%d\n", reg);
  71                 return -1;
  72         }
  73 
  74         v4l2_dbg(1, debug, sd, "write: %02x %02x\n", reg, val);
  75 
  76         for (i = 0; i < 3; i++)
  77                 if (i2c_smbus_write_byte_data(client,
  78                                 (reg << 1) | (val >> 8), val & 0xff) == 0)
  79                         return 0;
  80         v4l2_err(sd, "I2C: cannot write %03x to register R%d\n", val, reg);
  81         return -1;
  82 }
  83 
  84 static int wm8739_s_ctrl(struct v4l2_ctrl *ctrl)
  85 {
  86         struct v4l2_subdev *sd = to_sd(ctrl);
  87         struct wm8739_state *state = to_state(sd);
  88         unsigned int work_l, work_r;
  89         u8 vol_l;       /* +12dB to -34.5dB 1.5dB step (5bit) def:0dB */
  90         u8 vol_r;       /* +12dB to -34.5dB 1.5dB step (5bit) def:0dB */
  91         u16 mute;
  92 
  93         switch (ctrl->id) {
  94         case V4L2_CID_AUDIO_VOLUME:
  95                 break;
  96 
  97         default:
  98                 return -EINVAL;
  99         }
 100 
 101         /* normalize ( 65535 to 0 -> 31 to 0 (12dB to -34.5dB) ) */
 102         work_l = (min(65536 - state->balance->val, 32768) * state->volume->val) / 32768;
 103         work_r = (min(state->balance->val, 32768) * state->volume->val) / 32768;
 104 
 105         vol_l = (long)work_l * 31 / 65535;
 106         vol_r = (long)work_r * 31 / 65535;
 107 
 108         /* set audio volume etc. */
 109         mute = state->mute->val ? 0x80 : 0;
 110 
 111         /* Volume setting: bits 0-4, 0x1f = 12 dB, 0x00 = -34.5 dB
 112          * Default setting: 0x17 = 0 dB
 113          */
 114         wm8739_write(sd, R0, (vol_l & 0x1f) | mute);
 115         wm8739_write(sd, R1, (vol_r & 0x1f) | mute);
 116         return 0;
 117 }
 118 
 119 /* ------------------------------------------------------------------------ */
 120 
 121 static int wm8739_s_clock_freq(struct v4l2_subdev *sd, u32 audiofreq)
 122 {
 123         struct wm8739_state *state = to_state(sd);
 124 
 125         state->clock_freq = audiofreq;
 126         /* de-activate */
 127         wm8739_write(sd, R9, 0x000);
 128         switch (audiofreq) {
 129         case 44100:
 130                 /* 256fps, fs=44.1k */
 131                 wm8739_write(sd, R8, 0x020);
 132                 break;
 133         case 48000:
 134                 /* 256fps, fs=48k */
 135                 wm8739_write(sd, R8, 0x000);
 136                 break;
 137         case 32000:
 138                 /* 256fps, fs=32k */
 139                 wm8739_write(sd, R8, 0x018);
 140                 break;
 141         default:
 142                 break;
 143         }
 144         /* activate */
 145         wm8739_write(sd, R9, 0x001);
 146         return 0;
 147 }
 148 
 149 static int wm8739_log_status(struct v4l2_subdev *sd)
 150 {
 151         struct wm8739_state *state = to_state(sd);
 152 
 153         v4l2_info(sd, "Frequency: %u Hz\n", state->clock_freq);
 154         v4l2_ctrl_handler_log_status(&state->hdl, sd->name);
 155         return 0;
 156 }
 157 
 158 /* ----------------------------------------------------------------------- */
 159 
 160 static const struct v4l2_ctrl_ops wm8739_ctrl_ops = {
 161         .s_ctrl = wm8739_s_ctrl,
 162 };
 163 
 164 static const struct v4l2_subdev_core_ops wm8739_core_ops = {
 165         .log_status = wm8739_log_status,
 166 };
 167 
 168 static const struct v4l2_subdev_audio_ops wm8739_audio_ops = {
 169         .s_clock_freq = wm8739_s_clock_freq,
 170 };
 171 
 172 static const struct v4l2_subdev_ops wm8739_ops = {
 173         .core = &wm8739_core_ops,
 174         .audio = &wm8739_audio_ops,
 175 };
 176 
 177 /* ------------------------------------------------------------------------ */
 178 
 179 /* i2c implementation */
 180 
 181 static int wm8739_probe(struct i2c_client *client,
 182                         const struct i2c_device_id *id)
 183 {
 184         struct wm8739_state *state;
 185         struct v4l2_subdev *sd;
 186 
 187         /* Check if the adapter supports the needed features */
 188         if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 189                 return -EIO;
 190 
 191         v4l_info(client, "chip found @ 0x%x (%s)\n",
 192                         client->addr << 1, client->adapter->name);
 193 
 194         state = devm_kzalloc(&client->dev, sizeof(*state), GFP_KERNEL);
 195         if (state == NULL)
 196                 return -ENOMEM;
 197         sd = &state->sd;
 198         v4l2_i2c_subdev_init(sd, client, &wm8739_ops);
 199         v4l2_ctrl_handler_init(&state->hdl, 2);
 200         state->volume = v4l2_ctrl_new_std(&state->hdl, &wm8739_ctrl_ops,
 201                         V4L2_CID_AUDIO_VOLUME, 0, 65535, 65535 / 100, 50736);
 202         state->mute = v4l2_ctrl_new_std(&state->hdl, &wm8739_ctrl_ops,
 203                         V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0);
 204         state->balance = v4l2_ctrl_new_std(&state->hdl, &wm8739_ctrl_ops,
 205                         V4L2_CID_AUDIO_BALANCE, 0, 65535, 65535 / 100, 32768);
 206         sd->ctrl_handler = &state->hdl;
 207         if (state->hdl.error) {
 208                 int err = state->hdl.error;
 209 
 210                 v4l2_ctrl_handler_free(&state->hdl);
 211                 return err;
 212         }
 213         v4l2_ctrl_cluster(3, &state->volume);
 214 
 215         state->clock_freq = 48000;
 216 
 217         /* Initialize wm8739 */
 218 
 219         /* reset */
 220         wm8739_write(sd, R15, 0x00);
 221         /* filter setting, high path, offet clear */
 222         wm8739_write(sd, R5, 0x000);
 223         /* ADC, OSC, Power Off mode Disable */
 224         wm8739_write(sd, R6, 0x000);
 225         /* Digital Audio interface format:
 226            Enable Master mode, 24 bit, MSB first/left justified */
 227         wm8739_write(sd, R7, 0x049);
 228         /* sampling control: normal, 256fs, 48KHz sampling rate */
 229         wm8739_write(sd, R8, 0x000);
 230         /* activate */
 231         wm8739_write(sd, R9, 0x001);
 232         /* set volume/mute */
 233         v4l2_ctrl_handler_setup(&state->hdl);
 234         return 0;
 235 }
 236 
 237 static int wm8739_remove(struct i2c_client *client)
 238 {
 239         struct v4l2_subdev *sd = i2c_get_clientdata(client);
 240         struct wm8739_state *state = to_state(sd);
 241 
 242         v4l2_device_unregister_subdev(sd);
 243         v4l2_ctrl_handler_free(&state->hdl);
 244         return 0;
 245 }
 246 
 247 static const struct i2c_device_id wm8739_id[] = {
 248         { "wm8739", 0 },
 249         { }
 250 };
 251 MODULE_DEVICE_TABLE(i2c, wm8739_id);
 252 
 253 static struct i2c_driver wm8739_driver = {
 254         .driver = {
 255                 .name   = "wm8739",
 256         },
 257         .probe          = wm8739_probe,
 258         .remove         = wm8739_remove,
 259         .id_table       = wm8739_id,
 260 };
 261 
 262 module_i2c_driver(wm8739_driver);

/* [<][>][^][v][top][bottom][index][help] */