^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) friq.c (c) 1998 Grant R. Guenther <grant@torque.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) Under the terms of the GNU General Public License
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) friq.c is a low-level protocol driver for the Freecom "IQ"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) parallel port IDE adapter. Early versions of this adapter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) use the 'frpw' protocol.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) Freecom uses this adapter in a battery powered external
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) CD-ROM drive. It is also used in LS-120 drives by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) Maxell and Panasonic, and other devices.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) The battery powered drive requires software support to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) control the power to the drive. This module enables the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) drive power when the high level driver (pcd) is loaded
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) and disables it when the module is unloaded. Note, if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) the friq module is built in to the kernel, the power
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) will never be switched off, so other means should be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) used to conserve battery power.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) /* Changes:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) 1.01 GRG 1998.12.20 Added support for soft power switch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define FRIQ_VERSION "1.01"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include "paride.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define CMD(x) w2(4);w0(0xff);w0(0xff);w0(0x73);w0(0x73);\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) w0(0xc9);w0(0xc9);w0(0x26);w0(0x26);w0(x);w0(x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define j44(l,h) (((l>>4)&0x0f)|(h&0xf0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /* cont = 0 - access the IDE register file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) cont = 1 - access the IDE command set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) static int cont_map[2] = { 0x08, 0x10 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) static int friq_read_regr( PIA *pi, int cont, int regr )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) { int h,l,r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) r = regr + cont_map[cont];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) CMD(r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) w2(6); l = r1();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) w2(4); h = r1();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) w2(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) return j44(l,h);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static void friq_write_regr( PIA *pi, int cont, int regr, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) { int r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) r = regr + cont_map[cont];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) CMD(r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) w0(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) w2(5);w2(7);w2(5);w2(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static void friq_read_block_int( PIA *pi, char * buf, int count, int regr )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) { int h, l, k, ph;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) switch(pi->mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) case 0: CMD(regr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) for (k=0;k<count;k++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) w2(6); l = r1();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) w2(4); h = r1();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) buf[k] = j44(l,h);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) w2(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) case 1: ph = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) CMD(regr+0xc0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) w0(0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) for (k=0;k<count;k++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) w2(0xa4 + ph);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) buf[k] = r0();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) ph = 2 - ph;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) w2(0xac); w2(0xa4); w2(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) case 2: CMD(regr+0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) for (k=0;k<count-2;k++) buf[k] = r4();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) w2(0xac); w2(0xa4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) buf[count-2] = r4();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) buf[count-1] = r4();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) w2(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) case 3: CMD(regr+0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) for (k=0;k<(count/2)-1;k++) ((u16 *)buf)[k] = r4w();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) w2(0xac); w2(0xa4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) buf[count-2] = r4();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) buf[count-1] = r4();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) w2(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) case 4: CMD(regr+0x80);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) for (k=0;k<(count/4)-1;k++) ((u32 *)buf)[k] = r4l();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) buf[count-4] = r4();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) buf[count-3] = r4();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) w2(0xac); w2(0xa4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) buf[count-2] = r4();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) buf[count-1] = r4();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) w2(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) static void friq_read_block( PIA *pi, char * buf, int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) { friq_read_block_int(pi,buf,count,0x08);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) static void friq_write_block( PIA *pi, char * buf, int count )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) { int k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) switch(pi->mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) case 1: CMD(8); w2(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) for (k=0;k<count;k++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) w0(buf[k]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) w2(7);w2(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) w2(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) case 2: CMD(0xc8); w2(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) for (k=0;k<count;k++) w4(buf[k]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) w2(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) case 3: CMD(0xc8); w2(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) for (k=0;k<count/2;k++) w4w(((u16 *)buf)[k]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) w2(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) case 4: CMD(0xc8); w2(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) for (k=0;k<count/4;k++) w4l(((u32 *)buf)[k]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) w2(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) static void friq_connect ( PIA *pi )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) { pi->saved_r0 = r0();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) pi->saved_r2 = r2();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) w2(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) static void friq_disconnect ( PIA *pi )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) { CMD(0x20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) w0(pi->saved_r0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) w2(pi->saved_r2);
^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 friq_test_proto( PIA *pi, char * scratch, int verbose )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) { int j, k, r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) int e[2] = {0,0};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) pi->saved_r0 = r0();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) w0(0xff); udelay(20); CMD(0x3d); /* turn the power on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) udelay(500);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) w0(pi->saved_r0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) friq_connect(pi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) for (j=0;j<2;j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) friq_write_regr(pi,0,6,0xa0+j*0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) for (k=0;k<256;k++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) friq_write_regr(pi,0,2,k^0xaa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) friq_write_regr(pi,0,3,k^0x55);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) if (friq_read_regr(pi,0,2) != (k^0xaa)) e[j]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) friq_disconnect(pi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) friq_connect(pi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) friq_read_block_int(pi,scratch,512,0x10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) r = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) for (k=0;k<128;k++) if (scratch[k] != k) r++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) friq_disconnect(pi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) if (verbose) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) printk("%s: friq: port 0x%x, mode %d, test=(%d,%d,%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) pi->device,pi->port,pi->mode,e[0],e[1],r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) return (r || (e[0] && e[1]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) static void friq_log_adapter( PIA *pi, char * scratch, int verbose )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) { char *mode_string[6] = {"4-bit","8-bit",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) "EPP-8","EPP-16","EPP-32"};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) printk("%s: friq %s, Freecom IQ ASIC-2 adapter at 0x%x, ", pi->device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) FRIQ_VERSION,pi->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) printk("mode %d (%s), delay %d\n",pi->mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) mode_string[pi->mode],pi->delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) pi->private = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) friq_connect(pi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) CMD(0x9e); /* disable sleep timer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) friq_disconnect(pi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) static void friq_release_proto( PIA *pi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) if (pi->private) { /* turn off the power */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) friq_connect(pi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) CMD(0x1d); CMD(0x1e);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) friq_disconnect(pi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) pi->private = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) static struct pi_protocol friq = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) .name = "friq",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) .max_mode = 5,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) .epp_first = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) .default_delay = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) .max_units = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) .write_regr = friq_write_regr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) .read_regr = friq_read_regr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) .write_block = friq_write_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) .read_block = friq_read_block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) .connect = friq_connect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) .disconnect = friq_disconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) .test_proto = friq_test_proto,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) .log_adapter = friq_log_adapter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) .release_proto = friq_release_proto,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) static int __init friq_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) return paride_register(&friq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) static void __exit friq_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) paride_unregister(&friq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) module_init(friq_init)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) module_exit(friq_exit)