Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /* radio-trust.c - Trust FM Radio card driver for Linux 2.2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * by Eric Lammerts <eric@scintilla.utwente.nl>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Based on radio-aztech.c. Original notes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Adapted to support the Video for Linux API by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  * Russell Kroll <rkroll@exploits.org>.  Based on original tuner code by:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * Quay Ly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * Donald Song
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  * Jason Lewis      (jlewis@twilight.vtc.vsc.edu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13)  * Scott McGrath    (smcgrath@twilight.vtc.vsc.edu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)  * William McGrath  (wmcgrath@twilight.vtc.vsc.edu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@kernel.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <linux/videodev2.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include <media/v4l2-device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include <media/v4l2-ioctl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #include "radio-isa.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) MODULE_AUTHOR("Eric Lammerts, Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott McGrath, William McGrath");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) MODULE_DESCRIPTION("A driver for the Trust FM Radio card.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) MODULE_VERSION("0.1.99");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) /* acceptable ports: 0x350 (JP3 shorted), 0x358 (JP3 open) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #ifndef CONFIG_RADIO_TRUST_PORT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #define CONFIG_RADIO_TRUST_PORT -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #define TRUST_MAX 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) static int io[TRUST_MAX] = { [0] = CONFIG_RADIO_TRUST_PORT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 			      [1 ... (TRUST_MAX - 1)] = -1 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) static int radio_nr[TRUST_MAX] = { [0 ... (TRUST_MAX - 1)] = -1 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) module_param_array(io, int, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) MODULE_PARM_DESC(io, "I/O addresses of the Trust FM Radio card (0x350 or 0x358)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) module_param_array(radio_nr, int, NULL, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) MODULE_PARM_DESC(radio_nr, "Radio device numbers");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) struct trust {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	struct radio_isa_card isa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	int ioval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) static struct radio_isa_card *trust_alloc(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	struct trust *tr = kzalloc(sizeof(*tr), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	return tr ? &tr->isa : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) /* i2c addresses */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) #define TDA7318_ADDR 0x88
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) #define TSA6060T_ADDR 0xc4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) #define TR_DELAY do { inb(tr->isa.io); inb(tr->isa.io); inb(tr->isa.io); } while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) #define TR_SET_SCL outb(tr->ioval |= 2, tr->isa.io)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) #define TR_CLR_SCL outb(tr->ioval &= 0xfd, tr->isa.io)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) #define TR_SET_SDA outb(tr->ioval |= 1, tr->isa.io)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) #define TR_CLR_SDA outb(tr->ioval &= 0xfe, tr->isa.io)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) static void write_i2c(struct trust *tr, int n, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	unsigned char val, mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	va_list args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	va_start(args, n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	/* start condition */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	TR_SET_SDA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	TR_SET_SCL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	TR_DELAY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	TR_CLR_SDA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	TR_CLR_SCL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	TR_DELAY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	for (; n; n--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		val = va_arg(args, unsigned);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 		for (mask = 0x80; mask; mask >>= 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 			if (val & mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 				TR_SET_SDA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 				TR_CLR_SDA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 			TR_SET_SCL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 			TR_DELAY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 			TR_CLR_SCL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 			TR_DELAY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		/* acknowledge bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 		TR_SET_SDA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 		TR_SET_SCL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		TR_DELAY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		TR_CLR_SCL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 		TR_DELAY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	/* stop condition */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	TR_CLR_SDA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	TR_DELAY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	TR_SET_SCL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	TR_DELAY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	TR_SET_SDA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	TR_DELAY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	va_end(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) static int trust_s_mute_volume(struct radio_isa_card *isa, bool mute, int vol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	struct trust *tr = container_of(isa, struct trust, isa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	tr->ioval = (tr->ioval & 0xf7) | (mute << 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	outb(tr->ioval, isa->io);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	write_i2c(tr, 2, TDA7318_ADDR, vol ^ 0x1f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static int trust_s_stereo(struct radio_isa_card *isa, bool stereo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	struct trust *tr = container_of(isa, struct trust, isa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	tr->ioval = (tr->ioval & 0xfb) | (!stereo << 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	outb(tr->ioval, isa->io);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) static u32 trust_g_signal(struct radio_isa_card *isa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	int i, v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	for (i = 0, v = 0; i < 100; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 		v |= inb(isa->io);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	return (v & 1) ? 0 : 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) static int trust_s_frequency(struct radio_isa_card *isa, u32 freq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	struct trust *tr = container_of(isa, struct trust, isa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	freq /= 160;	/* Convert to 10 kHz units	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	freq += 1070;	/* Add 10.7 MHz IF		*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	write_i2c(tr, 5, TSA6060T_ADDR, (freq << 1) | 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 			freq >> 7, 0x60 | ((freq >> 15) & 1), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) static int basstreble2chip[15] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	0, 1, 2, 3, 4, 5, 6, 7, 14, 13, 12, 11, 10, 9, 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) static int trust_s_ctrl(struct v4l2_ctrl *ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	struct radio_isa_card *isa =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		container_of(ctrl->handler, struct radio_isa_card, hdl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	struct trust *tr = container_of(isa, struct trust, isa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	switch (ctrl->id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	case V4L2_CID_AUDIO_BASS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 		write_i2c(tr, 2, TDA7318_ADDR, 0x60 | basstreble2chip[ctrl->val]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	case V4L2_CID_AUDIO_TREBLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 		write_i2c(tr, 2, TDA7318_ADDR, 0x70 | basstreble2chip[ctrl->val]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) static const struct v4l2_ctrl_ops trust_ctrl_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	.s_ctrl = trust_s_ctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) static int trust_initialize(struct radio_isa_card *isa)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	struct trust *tr = container_of(isa, struct trust, isa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	tr->ioval = 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	write_i2c(tr, 2, TDA7318_ADDR, 0x80);	/* speaker att. LF = 0 dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 	write_i2c(tr, 2, TDA7318_ADDR, 0xa0);	/* speaker att. RF = 0 dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	write_i2c(tr, 2, TDA7318_ADDR, 0xc0);	/* speaker att. LR = 0 dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 	write_i2c(tr, 2, TDA7318_ADDR, 0xe0);	/* speaker att. RR = 0 dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	write_i2c(tr, 2, TDA7318_ADDR, 0x40);	/* stereo 1 input, gain = 18.75 dB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	v4l2_ctrl_new_std(&isa->hdl, &trust_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 				V4L2_CID_AUDIO_BASS, 0, 15, 1, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	v4l2_ctrl_new_std(&isa->hdl, &trust_ctrl_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 				V4L2_CID_AUDIO_TREBLE, 0, 15, 1, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	return isa->hdl.error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) static const struct radio_isa_ops trust_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	.init = trust_initialize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	.alloc = trust_alloc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	.s_mute_volume = trust_s_mute_volume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	.s_frequency = trust_s_frequency,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	.s_stereo = trust_s_stereo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	.g_signal = trust_g_signal,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) static const int trust_ioports[] = { 0x350, 0x358 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) static struct radio_isa_driver trust_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 		.match		= radio_isa_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 		.probe		= radio_isa_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 		.remove		= radio_isa_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 		.driver		= {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 			.name	= "radio-trust",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 		},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	.io_params = io,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	.radio_nr_params = radio_nr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	.io_ports = trust_ioports,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	.num_of_io_ports = ARRAY_SIZE(trust_ioports),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	.region_size = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	.card = "Trust FM Radio",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	.ops = &trust_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	.has_stereo = true,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	.max_volume = 31,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) static int __init trust_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	return isa_register_driver(&trust_driver.driver, TRUST_MAX);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) static void __exit trust_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	isa_unregister_driver(&trust_driver.driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) module_init(trust_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) module_exit(trust_exit);