1/* SF16-FMR2 and SF16-FMD2 radio driver for Linux 2 * Copyright (c) 2011 Ondrej Zary 3 * 4 * Original driver was (c) 2000-2002 Ziglio Frediano, freddy77@angelfire.com 5 * but almost nothing remained here after conversion to generic TEA575x 6 * implementation 7 */ 8 9#include <linux/delay.h> 10#include <linux/module.h> /* Modules */ 11#include <linux/init.h> /* Initdata */ 12#include <linux/slab.h> 13#include <linux/ioport.h> /* request_region */ 14#include <linux/io.h> /* outb, outb_p */ 15#include <linux/isa.h> 16#include <linux/pnp.h> 17#include <media/tea575x.h> 18 19MODULE_AUTHOR("Ondrej Zary"); 20MODULE_DESCRIPTION("MediaForte SF16-FMR2 and SF16-FMD2 FM radio card driver"); 21MODULE_LICENSE("GPL"); 22 23/* these cards can only use two different ports (0x384 and 0x284) */ 24#define FMR2_MAX 2 25 26static int radio_nr[FMR2_MAX] = { [0 ... (FMR2_MAX - 1)] = -1 }; 27module_param_array(radio_nr, int, NULL, 0444); 28MODULE_PARM_DESC(radio_nr, "Radio device numbers"); 29 30struct fmr2 { 31 int io; 32 struct v4l2_device v4l2_dev; 33 struct snd_tea575x tea; 34 struct v4l2_ctrl *volume; 35 struct v4l2_ctrl *balance; 36 bool is_fmd2; 37}; 38 39static int num_fmr2_cards; 40static struct fmr2 *fmr2_cards[FMR2_MAX]; 41static bool isa_registered; 42static bool pnp_registered; 43 44/* the port is hardwired on SF16-FMR2 */ 45#define FMR2_PORT 0x384 46 47/* TEA575x tuner pins */ 48#define STR_DATA (1 << 0) 49#define STR_CLK (1 << 1) 50#define STR_WREN (1 << 2) 51#define STR_MOST (1 << 3) 52/* PT2254A/TC9154A volume control pins */ 53#define PT_ST (1 << 4) 54#define PT_CK (1 << 5) 55#define PT_DATA (1 << 6) 56/* volume control presence pin */ 57#define FMR2_HASVOL (1 << 7) 58 59static void fmr2_tea575x_set_pins(struct snd_tea575x *tea, u8 pins) 60{ 61 struct fmr2 *fmr2 = tea->private_data; 62 u8 bits = 0; 63 64 bits |= (pins & TEA575X_DATA) ? STR_DATA : 0; 65 bits |= (pins & TEA575X_CLK) ? STR_CLK : 0; 66 /* WRITE_ENABLE is inverted, DATA must be high during read */ 67 bits |= (pins & TEA575X_WREN) ? 0 : STR_WREN | STR_DATA; 68 69 outb(bits, fmr2->io); 70} 71 72static u8 fmr2_tea575x_get_pins(struct snd_tea575x *tea) 73{ 74 struct fmr2 *fmr2 = tea->private_data; 75 u8 bits = inb(fmr2->io); 76 77 return ((bits & STR_DATA) ? TEA575X_DATA : 0) | 78 ((bits & STR_MOST) ? TEA575X_MOST : 0); 79} 80 81static void fmr2_tea575x_set_direction(struct snd_tea575x *tea, bool output) 82{ 83} 84 85static struct snd_tea575x_ops fmr2_tea_ops = { 86 .set_pins = fmr2_tea575x_set_pins, 87 .get_pins = fmr2_tea575x_get_pins, 88 .set_direction = fmr2_tea575x_set_direction, 89}; 90 91/* TC9154A/PT2254A volume control */ 92 93/* 18-bit shift register bit definitions */ 94#define TC9154A_ATT_MAJ_0DB (1 << 0) 95#define TC9154A_ATT_MAJ_10DB (1 << 1) 96#define TC9154A_ATT_MAJ_20DB (1 << 2) 97#define TC9154A_ATT_MAJ_30DB (1 << 3) 98#define TC9154A_ATT_MAJ_40DB (1 << 4) 99#define TC9154A_ATT_MAJ_50DB (1 << 5) 100#define TC9154A_ATT_MAJ_60DB (1 << 6) 101 102#define TC9154A_ATT_MIN_0DB (1 << 7) 103#define TC9154A_ATT_MIN_2DB (1 << 8) 104#define TC9154A_ATT_MIN_4DB (1 << 9) 105#define TC9154A_ATT_MIN_6DB (1 << 10) 106#define TC9154A_ATT_MIN_8DB (1 << 11) 107/* bit 12 is ignored */ 108#define TC9154A_CHANNEL_LEFT (1 << 13) 109#define TC9154A_CHANNEL_RIGHT (1 << 14) 110/* bits 15, 16, 17 must be 0 */ 111 112#define TC9154A_ATT_MAJ(x) (1 << x) 113#define TC9154A_ATT_MIN(x) (1 << (7 + x)) 114 115static void tc9154a_set_pins(struct fmr2 *fmr2, u8 pins) 116{ 117 if (!fmr2->tea.mute) 118 pins |= STR_WREN; 119 120 outb(pins, fmr2->io); 121} 122 123static void tc9154a_set_attenuation(struct fmr2 *fmr2, int att, u32 channel) 124{ 125 int i; 126 u32 reg; 127 u8 bit; 128 129 reg = TC9154A_ATT_MAJ(att / 10) | TC9154A_ATT_MIN((att % 10) / 2); 130 reg |= channel; 131 /* write 18-bit shift register, LSB first */ 132 for (i = 0; i < 18; i++) { 133 bit = reg & (1 << i) ? PT_DATA : 0; 134 tc9154a_set_pins(fmr2, bit); 135 udelay(5); 136 tc9154a_set_pins(fmr2, bit | PT_CK); 137 udelay(5); 138 tc9154a_set_pins(fmr2, bit); 139 } 140 141 /* latch register data */ 142 udelay(5); 143 tc9154a_set_pins(fmr2, PT_ST); 144 udelay(5); 145 tc9154a_set_pins(fmr2, 0); 146} 147 148static int fmr2_s_ctrl(struct v4l2_ctrl *ctrl) 149{ 150 struct snd_tea575x *tea = container_of(ctrl->handler, struct snd_tea575x, ctrl_handler); 151 struct fmr2 *fmr2 = tea->private_data; 152 int volume, balance, left, right; 153 154 switch (ctrl->id) { 155 case V4L2_CID_AUDIO_VOLUME: 156 volume = ctrl->val; 157 balance = fmr2->balance->cur.val; 158 break; 159 case V4L2_CID_AUDIO_BALANCE: 160 balance = ctrl->val; 161 volume = fmr2->volume->cur.val; 162 break; 163 default: 164 return -EINVAL; 165 } 166 167 left = right = volume; 168 if (balance < 0) 169 right = max(0, right + balance); 170 if (balance > 0) 171 left = max(0, left - balance); 172 173 tc9154a_set_attenuation(fmr2, abs(left - 68), TC9154A_CHANNEL_LEFT); 174 tc9154a_set_attenuation(fmr2, abs(right - 68), TC9154A_CHANNEL_RIGHT); 175 176 return 0; 177} 178 179static const struct v4l2_ctrl_ops fmr2_ctrl_ops = { 180 .s_ctrl = fmr2_s_ctrl, 181}; 182 183static int fmr2_tea_ext_init(struct snd_tea575x *tea) 184{ 185 struct fmr2 *fmr2 = tea->private_data; 186 187 /* FMR2 can have volume control, FMD2 can't (uses SB16 mixer) */ 188 if (!fmr2->is_fmd2 && inb(fmr2->io) & FMR2_HASVOL) { 189 fmr2->volume = v4l2_ctrl_new_std(&tea->ctrl_handler, &fmr2_ctrl_ops, V4L2_CID_AUDIO_VOLUME, 0, 68, 2, 56); 190 fmr2->balance = v4l2_ctrl_new_std(&tea->ctrl_handler, &fmr2_ctrl_ops, V4L2_CID_AUDIO_BALANCE, -68, 68, 2, 0); 191 if (tea->ctrl_handler.error) { 192 printk(KERN_ERR "radio-sf16fmr2: can't initialize controls\n"); 193 return tea->ctrl_handler.error; 194 } 195 } 196 197 return 0; 198} 199 200static struct pnp_device_id fmr2_pnp_ids[] = { 201 { .id = "MFRad13" }, /* tuner subdevice of SF16-FMD2 */ 202 { .id = "" } 203}; 204MODULE_DEVICE_TABLE(pnp, fmr2_pnp_ids); 205 206static int fmr2_probe(struct fmr2 *fmr2, struct device *pdev, int io) 207{ 208 int err, i; 209 char *card_name = fmr2->is_fmd2 ? "SF16-FMD2" : "SF16-FMR2"; 210 211 /* avoid errors if a card was already registered at given port */ 212 for (i = 0; i < num_fmr2_cards; i++) 213 if (io == fmr2_cards[i]->io) 214 return -EBUSY; 215 216 strlcpy(fmr2->v4l2_dev.name, "radio-sf16fmr2", 217 sizeof(fmr2->v4l2_dev.name)), 218 fmr2->io = io; 219 220 if (!request_region(fmr2->io, 2, fmr2->v4l2_dev.name)) { 221 printk(KERN_ERR "radio-sf16fmr2: I/O port 0x%x already in use\n", fmr2->io); 222 return -EBUSY; 223 } 224 225 dev_set_drvdata(pdev, fmr2); 226 err = v4l2_device_register(pdev, &fmr2->v4l2_dev); 227 if (err < 0) { 228 v4l2_err(&fmr2->v4l2_dev, "Could not register v4l2_device\n"); 229 release_region(fmr2->io, 2); 230 return err; 231 } 232 fmr2->tea.v4l2_dev = &fmr2->v4l2_dev; 233 fmr2->tea.private_data = fmr2; 234 fmr2->tea.radio_nr = radio_nr[num_fmr2_cards]; 235 fmr2->tea.ops = &fmr2_tea_ops; 236 fmr2->tea.ext_init = fmr2_tea_ext_init; 237 strlcpy(fmr2->tea.card, card_name, sizeof(fmr2->tea.card)); 238 snprintf(fmr2->tea.bus_info, sizeof(fmr2->tea.bus_info), "%s:%s", 239 fmr2->is_fmd2 ? "PnP" : "ISA", dev_name(pdev)); 240 241 if (snd_tea575x_init(&fmr2->tea, THIS_MODULE)) { 242 printk(KERN_ERR "radio-sf16fmr2: Unable to detect TEA575x tuner\n"); 243 release_region(fmr2->io, 2); 244 return -ENODEV; 245 } 246 247 printk(KERN_INFO "radio-sf16fmr2: %s radio card at 0x%x.\n", 248 card_name, fmr2->io); 249 return 0; 250} 251 252static int fmr2_isa_match(struct device *pdev, unsigned int ndev) 253{ 254 struct fmr2 *fmr2 = kzalloc(sizeof(*fmr2), GFP_KERNEL); 255 if (!fmr2) 256 return 0; 257 258 if (fmr2_probe(fmr2, pdev, FMR2_PORT)) { 259 kfree(fmr2); 260 return 0; 261 } 262 dev_set_drvdata(pdev, fmr2); 263 fmr2_cards[num_fmr2_cards++] = fmr2; 264 265 return 1; 266} 267 268static int fmr2_pnp_probe(struct pnp_dev *pdev, const struct pnp_device_id *id) 269{ 270 int ret; 271 struct fmr2 *fmr2 = kzalloc(sizeof(*fmr2), GFP_KERNEL); 272 if (!fmr2) 273 return -ENOMEM; 274 275 fmr2->is_fmd2 = true; 276 ret = fmr2_probe(fmr2, &pdev->dev, pnp_port_start(pdev, 0)); 277 if (ret) { 278 kfree(fmr2); 279 return ret; 280 } 281 pnp_set_drvdata(pdev, fmr2); 282 fmr2_cards[num_fmr2_cards++] = fmr2; 283 284 return 0; 285} 286 287static void fmr2_remove(struct fmr2 *fmr2) 288{ 289 snd_tea575x_exit(&fmr2->tea); 290 release_region(fmr2->io, 2); 291 v4l2_device_unregister(&fmr2->v4l2_dev); 292 kfree(fmr2); 293} 294 295static int fmr2_isa_remove(struct device *pdev, unsigned int ndev) 296{ 297 fmr2_remove(dev_get_drvdata(pdev)); 298 299 return 0; 300} 301 302static void fmr2_pnp_remove(struct pnp_dev *pdev) 303{ 304 fmr2_remove(pnp_get_drvdata(pdev)); 305 pnp_set_drvdata(pdev, NULL); 306} 307 308static struct isa_driver fmr2_isa_driver = { 309 .match = fmr2_isa_match, 310 .remove = fmr2_isa_remove, 311 .driver = { 312 .name = "radio-sf16fmr2", 313 }, 314}; 315 316static struct pnp_driver fmr2_pnp_driver = { 317 .name = "radio-sf16fmr2", 318 .id_table = fmr2_pnp_ids, 319 .probe = fmr2_pnp_probe, 320 .remove = fmr2_pnp_remove, 321}; 322 323static int __init fmr2_init(void) 324{ 325 int ret; 326 327 ret = pnp_register_driver(&fmr2_pnp_driver); 328 if (!ret) 329 pnp_registered = true; 330 ret = isa_register_driver(&fmr2_isa_driver, 1); 331 if (!ret) 332 isa_registered = true; 333 334 return (pnp_registered || isa_registered) ? 0 : ret; 335} 336 337static void __exit fmr2_exit(void) 338{ 339 if (pnp_registered) 340 pnp_unregister_driver(&fmr2_pnp_driver); 341 if (isa_registered) 342 isa_unregister_driver(&fmr2_isa_driver); 343} 344 345module_init(fmr2_init); 346module_exit(fmr2_exit); 347