00001
00002
00003
00004
00005
00006
00007 #include <linux/types.h>
00008 #include <linux/errno.h>
00009 #include <linux/init.h>
00010 #include <linux/string.h>
00011 #include <linux/ctype.h>
00012 #include <linux/kernel.h>
00013 #include <linux/module.h>
00014 #include <asm/io.h>
00015 #include <asm/delay.h>
00016 #include <asm/arch/pinmux.h>
00017 #include <asm/arch/hwregs/gio_defs.h>
00018 #include <asm/arch/hwregs/pinmux_defs.h>
00019 #include <asm/arch/hwregs/iop/iop_sw_cfg_defs.h>
00020
00021 #ifndef DEBUG
00022 #define DEBUG(x)
00023 #endif
00024
00025 struct crisv32_ioport crisv32_ioports[] =
00026 {
00027 {
00028 (unsigned long*)REG_ADDR(gio, regi_gio, rw_pa_oe),
00029 (unsigned long*)REG_ADDR(gio, regi_gio, rw_pa_dout),
00030 (unsigned long*)REG_ADDR(gio, regi_gio, r_pa_din),
00031 8
00032 },
00033 {
00034 (unsigned long*)REG_ADDR(gio, regi_gio, rw_pb_oe),
00035 (unsigned long*)REG_ADDR(gio, regi_gio, rw_pb_dout),
00036 (unsigned long*)REG_ADDR(gio, regi_gio, r_pb_din),
00037 18
00038 },
00039 {
00040 (unsigned long*)REG_ADDR(gio, regi_gio, rw_pc_oe),
00041 (unsigned long*)REG_ADDR(gio, regi_gio, rw_pc_dout),
00042 (unsigned long*)REG_ADDR(gio, regi_gio, r_pc_din),
00043 18
00044 },
00045 {
00046 (unsigned long*)REG_ADDR(gio, regi_gio, rw_pd_oe),
00047 (unsigned long*)REG_ADDR(gio, regi_gio, rw_pd_dout),
00048 (unsigned long*)REG_ADDR(gio, regi_gio, r_pd_din),
00049 18
00050 },
00051 {
00052 (unsigned long*)REG_ADDR(gio, regi_gio, rw_pe_oe),
00053 (unsigned long*)REG_ADDR(gio, regi_gio, rw_pe_dout),
00054 (unsigned long*)REG_ADDR(gio, regi_gio, r_pe_din),
00055 18
00056 }
00057 };
00058
00059 #define NBR_OF_PORTS sizeof(crisv32_ioports)/sizeof(struct crisv32_ioport)
00060
00061 struct crisv32_iopin crisv32_led_net0_green;
00062 struct crisv32_iopin crisv32_led_net0_red;
00063 struct crisv32_iopin crisv32_led_net1_green;
00064 struct crisv32_iopin crisv32_led_net1_red;
00065 struct crisv32_iopin crisv32_led2_green;
00066 struct crisv32_iopin crisv32_led2_red;
00067 struct crisv32_iopin crisv32_led3_green;
00068 struct crisv32_iopin crisv32_led3_red;
00069
00070
00071 static unsigned long io_dummy;
00072 static struct crisv32_ioport dummy_port =
00073 {
00074 &io_dummy,
00075 &io_dummy,
00076 &io_dummy,
00077 18
00078 };
00079 static struct crisv32_iopin dummy_led =
00080 {
00081 &dummy_port,
00082 0
00083 };
00084
00085 int _353_io_board_present = 1;
00086 EXPORT_SYMBOL(_353_io_board_present);
00087
00088 void _353_configure(void) {
00089 int pd16_level = 1;
00090 printk("Check hardware configuration of Elphel 353 camera\n");
00091
00092
00093
00094
00095
00096
00097 reg_iop_sw_cfg_rw_pinmapping _rw_pinmapping = REG_RD(iop_sw_cfg, regi_iop_sw_cfg, rw_pinmapping);
00098 reg_iop_sw_cfg_rw_pinmapping prev_rw_pinmapping = _rw_pinmapping;
00099 _rw_pinmapping.gio3_0 = 2;
00100 REG_WR(iop_sw_cfg, regi_iop_sw_cfg, rw_pinmapping, _rw_pinmapping);
00101
00102 reg_pinmux_rw_pd_gio _rw_pd_gio = REG_RD(pinmux, regi_pinmux, rw_pd_gio);
00103 reg_pinmux_rw_pd_gio prev_rw_pd_gio = _rw_pd_gio;
00104 _rw_pd_gio.pd16 = 1;
00105 REG_WR(pinmux, regi_pinmux, rw_pd_gio, _rw_pd_gio);
00106
00107 reg_pinmux_rw_pd_iop _rw_pd_iop = REG_RD(pinmux, regi_pinmux, rw_pd_iop);
00108 reg_pinmux_rw_pd_iop prev_rw_pd_iop = _rw_pd_iop;
00109 _rw_pd_iop.pd16 = 1;
00110 REG_WR(pinmux, regi_pinmux, rw_pd_iop, _rw_pd_iop);
00112 reg_gio_rw_pd_oe _pd_oe = REG_RD(gio, regi_gio, rw_pd_oe);
00113 reg_gio_rw_pd_oe prev_pd_oe = _pd_oe;
00114 _pd_oe.oe |= 1 << 16;
00115 REG_WR(gio, regi_gio, rw_pd_oe, _pd_oe);
00117 reg_gio_r_pd_din _pd_din;
00118
00119
00121
00122 reg_gio_rw_pd_dout _pd_dout;
00123 _pd_dout.data = 1 << 16;
00124 REG_WR(gio, regi_gio, rw_pd_dout, _pd_dout);
00125 udelay(1);
00126
00127
00129
00130 _pd_oe.oe &= ~(1 << 16);
00131 REG_WR(gio, regi_gio, rw_pd_oe, _pd_oe);
00132 udelay(10);
00133 _pd_din = REG_RD(gio, regi_gio, r_pd_din);
00134
00135 pd16_level = _pd_din.data >> 16;
00136 pd16_level &= 0x0001;
00137
00138
00139
00140
00141 REG_WR(gio, regi_gio, rw_pd_oe, prev_pd_oe);
00142 REG_WR(pinmux, regi_pinmux, rw_pd_iop, prev_rw_pd_iop);
00143 REG_WR(pinmux, regi_pinmux, rw_pd_gio, prev_rw_pd_gio);
00144 REG_WR(iop_sw_cfg, regi_iop_sw_cfg, rw_pinmapping, prev_rw_pinmapping);
00146 if(pd16_level) {
00147 printk("Elphel 10349/10369 IO extension board is not present\n");
00148 _353_io_board_present = 0;
00149 } else {
00150 printk("Elphel 10349/10369 IO extension board is present\n");
00151 _353_io_board_present = 1;
00152 }
00153
00154 }
00155
00156 static int __init crisv32_io_init(void)
00157 {
00158 int ret = 0;
00159
00160 u32 i;
00161
00162 _353_configure();
00163
00164
00165 for (i = 0; i < ARRAY_SIZE(crisv32_ioports); i++)
00166 spin_lock_init (&crisv32_ioports[i].lock);
00167 spin_lock_init (&dummy_port.lock);
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201 crisv32_led_net0_red = dummy_led;
00202 crisv32_led_net1_red = dummy_led;
00203
00204 return ret;
00205 }
00206
00207 __initcall(crisv32_io_init);
00208
00209 int crisv32_io_get(struct crisv32_iopin* iopin,
00210 unsigned int port, unsigned int pin)
00211 {
00212 if (port > NBR_OF_PORTS)
00213 return -EINVAL;
00214 if (port > crisv32_ioports[port].pin_count)
00215 return -EINVAL;
00216
00217 iopin->bit = 1 << pin;
00218 iopin->port = &crisv32_ioports[port];
00219
00220
00221
00222 if (port != 0 && crisv32_pinmux_alloc(port-1, pin, pin, pinmux_gpio))
00223 return -EIO;
00224 DEBUG(printk("crisv32_io_get: Allocated pin %d on port %d\n", pin, port ));
00225
00226 return 0;
00227 }
00228
00229 int crisv32_io_get_name(struct crisv32_iopin* iopin,
00230 const char* name)
00231 {
00232 int port;
00233 int pin;
00234
00235 if (toupper(*name) == 'P')
00236 name++;
00237
00238 if (toupper(*name) < 'A' || toupper(*name) > 'E')
00239 return -EINVAL;
00240
00241 port = toupper(*name) - 'A';
00242 name++;
00243 pin = simple_strtoul(name, NULL, 10);
00244
00245 if (pin < 0 || pin > crisv32_ioports[port].pin_count)
00246 return -EINVAL;
00247
00248 iopin->bit = 1 << pin;
00249 iopin->port = &crisv32_ioports[port];
00250
00251
00252
00253 if (port != 0 && crisv32_pinmux_alloc(port-1, pin, pin, pinmux_gpio))
00254 return -EIO;
00255
00256 DEBUG(printk("crisv32_io_get_name: Allocated pin %d on port %d\n", pin, port));
00257 return 0;
00258 }
00259
00260 #ifdef CONFIG_PCI
00261
00262 struct cris_io_operations* cris_iops = NULL;
00263 EXPORT_SYMBOL(cris_iops);
00264 #endif
00265