0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #include <linux/module.h>
0020 #include <linux/init.h>
0021 #include <linux/ioport.h>
0022 #include <linux/videodev2.h>
0023 #include <linux/io.h>
0024 #include <linux/slab.h>
0025 #include <media/v4l2-device.h>
0026 #include <media/v4l2-ioctl.h>
0027 #include "radio-isa.h"
0028
0029 MODULE_AUTHOR("Eric Lammerts, Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath");
0030 MODULE_DESCRIPTION("A driver for the Trust FM Radio card.");
0031 MODULE_LICENSE("GPL");
0032 MODULE_VERSION("0.1.99");
0033
0034
0035
0036 #ifndef CONFIG_RADIO_TRUST_PORT
0037 #define CONFIG_RADIO_TRUST_PORT -1
0038 #endif
0039
0040 #define TRUST_MAX 2
0041
0042 static int io[TRUST_MAX] = { [0] = CONFIG_RADIO_TRUST_PORT,
0043 [1 ... (TRUST_MAX - 1)] = -1 };
0044 static int radio_nr[TRUST_MAX] = { [0 ... (TRUST_MAX - 1)] = -1 };
0045
0046 module_param_array(io, int, NULL, 0444);
0047 MODULE_PARM_DESC(io, "I/O addresses of the Trust FM Radio card (0x350 or 0x358)");
0048 module_param_array(radio_nr, int, NULL, 0444);
0049 MODULE_PARM_DESC(radio_nr, "Radio device numbers");
0050
0051 struct trust {
0052 struct radio_isa_card isa;
0053 int ioval;
0054 };
0055
0056 static struct radio_isa_card *trust_alloc(void)
0057 {
0058 struct trust *tr = kzalloc(sizeof(*tr), GFP_KERNEL);
0059
0060 return tr ? &tr->isa : NULL;
0061 }
0062
0063
0064 #define TDA7318_ADDR 0x88
0065 #define TSA6060T_ADDR 0xc4
0066
0067 #define TR_DELAY do { inb(tr->isa.io); inb(tr->isa.io); inb(tr->isa.io); } while (0)
0068 #define TR_SET_SCL outb(tr->ioval |= 2, tr->isa.io)
0069 #define TR_CLR_SCL outb(tr->ioval &= 0xfd, tr->isa.io)
0070 #define TR_SET_SDA outb(tr->ioval |= 1, tr->isa.io)
0071 #define TR_CLR_SDA outb(tr->ioval &= 0xfe, tr->isa.io)
0072
0073 static void write_i2c(struct trust *tr, int n, ...)
0074 {
0075 unsigned char val, mask;
0076 va_list args;
0077
0078 va_start(args, n);
0079
0080
0081 TR_SET_SDA;
0082 TR_SET_SCL;
0083 TR_DELAY;
0084 TR_CLR_SDA;
0085 TR_CLR_SCL;
0086 TR_DELAY;
0087
0088 for (; n; n--) {
0089 val = va_arg(args, unsigned);
0090 for (mask = 0x80; mask; mask >>= 1) {
0091 if (val & mask)
0092 TR_SET_SDA;
0093 else
0094 TR_CLR_SDA;
0095 TR_SET_SCL;
0096 TR_DELAY;
0097 TR_CLR_SCL;
0098 TR_DELAY;
0099 }
0100
0101 TR_SET_SDA;
0102 TR_SET_SCL;
0103 TR_DELAY;
0104 TR_CLR_SCL;
0105 TR_DELAY;
0106 }
0107
0108
0109 TR_CLR_SDA;
0110 TR_DELAY;
0111 TR_SET_SCL;
0112 TR_DELAY;
0113 TR_SET_SDA;
0114 TR_DELAY;
0115
0116 va_end(args);
0117 }
0118
0119 static int trust_s_mute_volume(struct radio_isa_card *isa, bool mute, int vol)
0120 {
0121 struct trust *tr = container_of(isa, struct trust, isa);
0122
0123 tr->ioval = (tr->ioval & 0xf7) | (mute << 3);
0124 outb(tr->ioval, isa->io);
0125 write_i2c(tr, 2, TDA7318_ADDR, vol ^ 0x1f);
0126 return 0;
0127 }
0128
0129 static int trust_s_stereo(struct radio_isa_card *isa, bool stereo)
0130 {
0131 struct trust *tr = container_of(isa, struct trust, isa);
0132
0133 tr->ioval = (tr->ioval & 0xfb) | (!stereo << 2);
0134 outb(tr->ioval, isa->io);
0135 return 0;
0136 }
0137
0138 static u32 trust_g_signal(struct radio_isa_card *isa)
0139 {
0140 int i, v;
0141
0142 for (i = 0, v = 0; i < 100; i++)
0143 v |= inb(isa->io);
0144 return (v & 1) ? 0 : 0xffff;
0145 }
0146
0147 static int trust_s_frequency(struct radio_isa_card *isa, u32 freq)
0148 {
0149 struct trust *tr = container_of(isa, struct trust, isa);
0150
0151 freq /= 160;
0152 freq += 1070;
0153 write_i2c(tr, 5, TSA6060T_ADDR, (freq << 1) | 1,
0154 freq >> 7, 0x60 | ((freq >> 15) & 1), 0);
0155 return 0;
0156 }
0157
0158 static int basstreble2chip[15] = {
0159 0, 1, 2, 3, 4, 5, 6, 7, 14, 13, 12, 11, 10, 9, 8
0160 };
0161
0162 static int trust_s_ctrl(struct v4l2_ctrl *ctrl)
0163 {
0164 struct radio_isa_card *isa =
0165 container_of(ctrl->handler, struct radio_isa_card, hdl);
0166 struct trust *tr = container_of(isa, struct trust, isa);
0167
0168 switch (ctrl->id) {
0169 case V4L2_CID_AUDIO_BASS:
0170 write_i2c(tr, 2, TDA7318_ADDR, 0x60 | basstreble2chip[ctrl->val]);
0171 return 0;
0172 case V4L2_CID_AUDIO_TREBLE:
0173 write_i2c(tr, 2, TDA7318_ADDR, 0x70 | basstreble2chip[ctrl->val]);
0174 return 0;
0175 }
0176 return -EINVAL;
0177 }
0178
0179 static const struct v4l2_ctrl_ops trust_ctrl_ops = {
0180 .s_ctrl = trust_s_ctrl,
0181 };
0182
0183 static int trust_initialize(struct radio_isa_card *isa)
0184 {
0185 struct trust *tr = container_of(isa, struct trust, isa);
0186
0187 tr->ioval = 0xf;
0188 write_i2c(tr, 2, TDA7318_ADDR, 0x80);
0189 write_i2c(tr, 2, TDA7318_ADDR, 0xa0);
0190 write_i2c(tr, 2, TDA7318_ADDR, 0xc0);
0191 write_i2c(tr, 2, TDA7318_ADDR, 0xe0);
0192 write_i2c(tr, 2, TDA7318_ADDR, 0x40);
0193
0194 v4l2_ctrl_new_std(&isa->hdl, &trust_ctrl_ops,
0195 V4L2_CID_AUDIO_BASS, 0, 15, 1, 8);
0196 v4l2_ctrl_new_std(&isa->hdl, &trust_ctrl_ops,
0197 V4L2_CID_AUDIO_TREBLE, 0, 15, 1, 8);
0198 return isa->hdl.error;
0199 }
0200
0201 static const struct radio_isa_ops trust_ops = {
0202 .init = trust_initialize,
0203 .alloc = trust_alloc,
0204 .s_mute_volume = trust_s_mute_volume,
0205 .s_frequency = trust_s_frequency,
0206 .s_stereo = trust_s_stereo,
0207 .g_signal = trust_g_signal,
0208 };
0209
0210 static const int trust_ioports[] = { 0x350, 0x358 };
0211
0212 static struct radio_isa_driver trust_driver = {
0213 .driver = {
0214 .match = radio_isa_match,
0215 .probe = radio_isa_probe,
0216 .remove = radio_isa_remove,
0217 .driver = {
0218 .name = "radio-trust",
0219 },
0220 },
0221 .io_params = io,
0222 .radio_nr_params = radio_nr,
0223 .io_ports = trust_ioports,
0224 .num_of_io_ports = ARRAY_SIZE(trust_ioports),
0225 .region_size = 2,
0226 .card = "Trust FM Radio",
0227 .ops = &trust_ops,
0228 .has_stereo = true,
0229 .max_volume = 31,
0230 };
0231
0232 static int __init trust_init(void)
0233 {
0234 return isa_register_driver(&trust_driver.driver, TRUST_MAX);
0235 }
0236
0237 static void __exit trust_exit(void)
0238 {
0239 isa_unregister_driver(&trust_driver.driver);
0240 }
0241
0242 module_init(trust_init);
0243 module_exit(trust_exit);