root/drivers/mfd/wl1273-core.c

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

DEFINITIONS

This source file includes following definitions.
  1. wl1273_fm_read_reg
  2. wl1273_fm_write_cmd
  3. wl1273_fm_write_data
  4. wl1273_fm_set_audio
  5. wl1273_fm_set_volume
  6. wl1273_core_probe
  7. wl1273_core_init
  8. wl1273_core_exit

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * MFD driver for wl1273 FM radio and audio codec submodules.
   4  *
   5  * Copyright (C) 2011 Nokia Corporation
   6  * Author: Matti Aaltonen <matti.j.aaltonen@nokia.com>
   7  */
   8 
   9 #include <linux/mfd/wl1273-core.h>
  10 #include <linux/slab.h>
  11 #include <linux/module.h>
  12 
  13 #define DRIVER_DESC "WL1273 FM Radio Core"
  14 
  15 static const struct i2c_device_id wl1273_driver_id_table[] = {
  16         { WL1273_FM_DRIVER_NAME, 0 },
  17         { }
  18 };
  19 MODULE_DEVICE_TABLE(i2c, wl1273_driver_id_table);
  20 
  21 static int wl1273_fm_read_reg(struct wl1273_core *core, u8 reg, u16 *value)
  22 {
  23         struct i2c_client *client = core->client;
  24         u8 b[2];
  25         int r;
  26 
  27         r = i2c_smbus_read_i2c_block_data(client, reg, sizeof(b), b);
  28         if (r != 2) {
  29                 dev_err(&client->dev, "%s: Read: %d fails.\n", __func__, reg);
  30                 return -EREMOTEIO;
  31         }
  32 
  33         *value = (u16)b[0] << 8 | b[1];
  34 
  35         return 0;
  36 }
  37 
  38 static int wl1273_fm_write_cmd(struct wl1273_core *core, u8 cmd, u16 param)
  39 {
  40         struct i2c_client *client = core->client;
  41         u8 buf[] = { (param >> 8) & 0xff, param & 0xff };
  42         int r;
  43 
  44         r = i2c_smbus_write_i2c_block_data(client, cmd, sizeof(buf), buf);
  45         if (r) {
  46                 dev_err(&client->dev, "%s: Cmd: %d fails.\n", __func__, cmd);
  47                 return r;
  48         }
  49 
  50         return 0;
  51 }
  52 
  53 static int wl1273_fm_write_data(struct wl1273_core *core, u8 *data, u16 len)
  54 {
  55         struct i2c_client *client = core->client;
  56         struct i2c_msg msg;
  57         int r;
  58 
  59         msg.addr = client->addr;
  60         msg.flags = 0;
  61         msg.buf = data;
  62         msg.len = len;
  63 
  64         r = i2c_transfer(client->adapter, &msg, 1);
  65         if (r != 1) {
  66                 dev_err(&client->dev, "%s: write error.\n", __func__);
  67                 return -EREMOTEIO;
  68         }
  69 
  70         return 0;
  71 }
  72 
  73 /**
  74  * wl1273_fm_set_audio() -      Set audio mode.
  75  * @core:                       A pointer to the device struct.
  76  * @new_mode:                   The new audio mode.
  77  *
  78  * Audio modes are WL1273_AUDIO_DIGITAL and WL1273_AUDIO_ANALOG.
  79  */
  80 static int wl1273_fm_set_audio(struct wl1273_core *core, unsigned int new_mode)
  81 {
  82         int r = 0;
  83 
  84         if (core->mode == WL1273_MODE_OFF ||
  85             core->mode == WL1273_MODE_SUSPENDED)
  86                 return -EPERM;
  87 
  88         if (core->mode == WL1273_MODE_RX && new_mode == WL1273_AUDIO_DIGITAL) {
  89                 r = wl1273_fm_write_cmd(core, WL1273_PCM_MODE_SET,
  90                                         WL1273_PCM_DEF_MODE);
  91                 if (r)
  92                         goto out;
  93 
  94                 r = wl1273_fm_write_cmd(core, WL1273_I2S_MODE_CONFIG_SET,
  95                                         core->i2s_mode);
  96                 if (r)
  97                         goto out;
  98 
  99                 r = wl1273_fm_write_cmd(core, WL1273_AUDIO_ENABLE,
 100                                         WL1273_AUDIO_ENABLE_I2S);
 101                 if (r)
 102                         goto out;
 103 
 104         } else if (core->mode == WL1273_MODE_RX &&
 105                    new_mode == WL1273_AUDIO_ANALOG) {
 106                 r = wl1273_fm_write_cmd(core, WL1273_AUDIO_ENABLE,
 107                                         WL1273_AUDIO_ENABLE_ANALOG);
 108                 if (r)
 109                         goto out;
 110 
 111         } else if (core->mode == WL1273_MODE_TX &&
 112                    new_mode == WL1273_AUDIO_DIGITAL) {
 113                 r = wl1273_fm_write_cmd(core, WL1273_I2S_MODE_CONFIG_SET,
 114                                         core->i2s_mode);
 115                 if (r)
 116                         goto out;
 117 
 118                 r = wl1273_fm_write_cmd(core, WL1273_AUDIO_IO_SET,
 119                                         WL1273_AUDIO_IO_SET_I2S);
 120                 if (r)
 121                         goto out;
 122 
 123         } else if (core->mode == WL1273_MODE_TX &&
 124                    new_mode == WL1273_AUDIO_ANALOG) {
 125                 r = wl1273_fm_write_cmd(core, WL1273_AUDIO_IO_SET,
 126                                         WL1273_AUDIO_IO_SET_ANALOG);
 127                 if (r)
 128                         goto out;
 129         }
 130 
 131         core->audio_mode = new_mode;
 132 out:
 133         return r;
 134 }
 135 
 136 /**
 137  * wl1273_fm_set_volume() -     Set volume.
 138  * @core:                       A pointer to the device struct.
 139  * @volume:                     The new volume value.
 140  */
 141 static int wl1273_fm_set_volume(struct wl1273_core *core, unsigned int volume)
 142 {
 143         int r;
 144 
 145         if (volume > WL1273_MAX_VOLUME)
 146                 return -EINVAL;
 147 
 148         if (core->volume == volume)
 149                 return 0;
 150 
 151         r = wl1273_fm_write_cmd(core, WL1273_VOLUME_SET, volume);
 152         if (r)
 153                 return r;
 154 
 155         core->volume = volume;
 156         return 0;
 157 }
 158 
 159 static int wl1273_core_probe(struct i2c_client *client,
 160                                        const struct i2c_device_id *id)
 161 {
 162         struct wl1273_fm_platform_data *pdata = dev_get_platdata(&client->dev);
 163         struct wl1273_core *core;
 164         struct mfd_cell *cell;
 165         int children = 0;
 166         int r = 0;
 167 
 168         dev_dbg(&client->dev, "%s\n", __func__);
 169 
 170         if (!pdata) {
 171                 dev_err(&client->dev, "No platform data.\n");
 172                 return -EINVAL;
 173         }
 174 
 175         if (!(pdata->children & WL1273_RADIO_CHILD)) {
 176                 dev_err(&client->dev, "Cannot function without radio child.\n");
 177                 return -EINVAL;
 178         }
 179 
 180         core = devm_kzalloc(&client->dev, sizeof(*core), GFP_KERNEL);
 181         if (!core)
 182                 return -ENOMEM;
 183 
 184         core->pdata = pdata;
 185         core->client = client;
 186         mutex_init(&core->lock);
 187 
 188         i2c_set_clientdata(client, core);
 189 
 190         dev_dbg(&client->dev, "%s: Have V4L2.\n", __func__);
 191 
 192         cell = &core->cells[children];
 193         cell->name = "wl1273_fm_radio";
 194         cell->platform_data = &core;
 195         cell->pdata_size = sizeof(core);
 196         children++;
 197 
 198         core->read = wl1273_fm_read_reg;
 199         core->write = wl1273_fm_write_cmd;
 200         core->write_data = wl1273_fm_write_data;
 201         core->set_audio = wl1273_fm_set_audio;
 202         core->set_volume = wl1273_fm_set_volume;
 203 
 204         if (pdata->children & WL1273_CODEC_CHILD) {
 205                 cell = &core->cells[children];
 206 
 207                 dev_dbg(&client->dev, "%s: Have codec.\n", __func__);
 208                 cell->name = "wl1273-codec";
 209                 cell->platform_data = &core;
 210                 cell->pdata_size = sizeof(core);
 211                 children++;
 212         }
 213 
 214         dev_dbg(&client->dev, "%s: number of children: %d.\n",
 215                 __func__, children);
 216 
 217         r = devm_mfd_add_devices(&client->dev, -1, core->cells,
 218                                  children, NULL, 0, NULL);
 219         if (r)
 220                 goto err;
 221 
 222         return 0;
 223 
 224 err:
 225         pdata->free_resources();
 226 
 227         dev_dbg(&client->dev, "%s\n", __func__);
 228 
 229         return r;
 230 }
 231 
 232 static struct i2c_driver wl1273_core_driver = {
 233         .driver = {
 234                 .name = WL1273_FM_DRIVER_NAME,
 235         },
 236         .probe = wl1273_core_probe,
 237         .id_table = wl1273_driver_id_table,
 238 };
 239 
 240 static int __init wl1273_core_init(void)
 241 {
 242         int r;
 243 
 244         r = i2c_add_driver(&wl1273_core_driver);
 245         if (r) {
 246                 pr_err(WL1273_FM_DRIVER_NAME
 247                        ": driver registration failed\n");
 248                 return r;
 249         }
 250 
 251         return r;
 252 }
 253 
 254 static void __exit wl1273_core_exit(void)
 255 {
 256         i2c_del_driver(&wl1273_core_driver);
 257 }
 258 late_initcall(wl1273_core_init);
 259 module_exit(wl1273_core_exit);
 260 
 261 MODULE_AUTHOR("Matti Aaltonen <matti.j.aaltonen@nokia.com>");
 262 MODULE_DESCRIPTION(DRIVER_DESC);
 263 MODULE_LICENSE("GPL");

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