Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-elphel
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
Elphel
linux-elphel
Commits
804b8db1
Commit
804b8db1
authored
Aug 07, 2016
by
Andrey Filippov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
added detect_sensor module
parent
4f108db9
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
468 additions
and
18 deletions
+468
-18
Makefile
src/drivers/elphel/Makefile
+1
-0
detect_sensors.c
src/drivers/elphel/detect_sensors.c
+389
-0
detect_sensors.h
src/drivers/elphel/detect_sensors.h
+28
-0
pgm_functions.c
src/drivers/elphel/pgm_functions.c
+20
-11
pgm_functions.h
src/drivers/elphel/pgm_functions.h
+17
-2
x393_videomem.c
src/drivers/elphel/x393_videomem.c
+4
-4
c313a.h
src/include/elphel/c313a.h
+8
-1
driver_numbers.h
src/include/elphel/driver_numbers.h
+1
-0
No files found.
src/drivers/elphel/Makefile
View file @
804b8db1
...
...
@@ -32,3 +32,4 @@ obj-$(CONFIG_ELPHEL393) += imu_log393.o
obj-$(CONFIG_ELPHEL393)
+=
cxi2c.o
obj-$(CONFIG_ELPHEL393)
+=
x393_videomem.o
obj-$(CONFIG_ELPHEL393)
+=
detect_sensors.o
\ No newline at end of file
src/drivers/elphel/detect_sensors.c
0 → 100644
View file @
804b8db1
/***************************************************************************//**
* @file detect_sensors.c
* @brief Determine sensor boards attached to each of the ports. Use
* Device Tree, sysfs to set sensor types per port. Add autodetection
* (using pullup/pull downs) later
* @copyright Copyright 2016 (C) Elphel, Inc.
* @par <b>License</b>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/
//#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/of_device.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/string.h>
//#include <asm/outercache.h> // TODO: Implement cache operations for the membridge !!!!
//#include <asm/cacheflush.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include "x393.h"
//#include "x393_detect_sensors.h"
#include <elphel/driver_numbers.h>
#include <elphel/c313a.h>
#include "mt9x001.h"
#include "multi10359.h"
#include "detect_sensors.h"
#define DETECT_SENSORS_MODULE_DESCRIPTION "Detect sensor type(s) attached to each of the ports"
#define DETECT_SENSORS_DRIVER_NAME "detect_sensors"
#define OF_PREFIX_NAME "elphel393-detect_sensors"
struct
sensor_port_config_t
{
u32
mux
;
///< sensor multiplexer, currently 0 (SENSOR_DETECT, SENSOR_MUX_10359 or SENSOR_NONE)
u32
sensor
[
MAX_SENSORS
];
///< Without mux only [0] is used, with 10359 - 0..2 are used (i2c addressing is shifted so 0 is broadcast)
};
static
struct
sensor_port_config_t
sensorPortConfig
[]
=
{
{.
mux
=
SENSOR_NONE
,.
sensor
=
{
SENSOR_NONE
,
SENSOR_NONE
,
SENSOR_NONE
,
SENSOR_NONE
}},
{.
mux
=
SENSOR_NONE
,.
sensor
=
{
SENSOR_NONE
,
SENSOR_NONE
,
SENSOR_NONE
,
SENSOR_NONE
}},
{.
mux
=
SENSOR_NONE
,.
sensor
=
{
SENSOR_NONE
,
SENSOR_NONE
,
SENSOR_NONE
,
SENSOR_NONE
}},
{.
mux
=
SENSOR_NONE
,.
sensor
=
{
SENSOR_NONE
,
SENSOR_NONE
,
SENSOR_NONE
,
SENSOR_NONE
}}
};
//struct sensor_port_config_t *pSensorPortConfig;
static
const
struct
of_device_id
elphel393_detect_sensors_of_match
[];
static
struct
device
*
g_dev_ptr
;
///< Global pointer to basic device structure. This pointer is used in debugfs output functions
struct
sensor_name_t
{
const
char
*
name
;
u32
code
;
int
type
;
///< +1 - applicable to sensors, +2 - applicable to multiplexers
};
const
struct
sensor_name_t
sensor_names
[]
=
{
{.
name
=
"detect"
,
.
type
=
3
,
.
code
=
0
},
// to be automatically detected
{.
name
=
"none"
,
.
type
=
3
,
.
code
=
SENSOR_NONE
},
// no device attached
{.
name
=
"mux10359"
,
.
type
=
2
,
.
code
=
SENSOR_MUX_10359
},
// no device attached
{.
name
=
"zr32112"
,
.
type
=
1
,
.
code
=
SENSOR_ZR32112
},
// Zoran ZR32112
{.
name
=
"zr32212"
,
.
type
=
1
,
.
code
=
SENSOR_ZR32212
},
// Zoran ZR32212
{.
name
=
"kac1310"
,
.
type
=
1
,
.
code
=
SENSOR_KAC1310
},
// Kodak KAC1310
{.
name
=
"kac5000"
,
.
type
=
1
,
.
code
=
SENSOR_KAC5000
},
// Kodak KAC5000
{.
name
=
"mi1300"
,
.
type
=
1
,
.
code
=
SENSOR_MI1300
},
// Micron MI1300
{.
name
=
"mt9m001"
,
.
type
=
1
,
.
code
=
SENSOR_MT9M001
},
// MT9M001
{.
name
=
"mt9d001"
,
.
type
=
1
,
.
code
=
SENSOR_MT9D001
},
// MT9D001
{.
name
=
"mt9t001"
,
.
type
=
1
,
.
code
=
SENSOR_MT9T001
},
// MT9T001
{.
name
=
"mt9p006"
,
.
type
=
1
,
.
code
=
SENSOR_MT9P006
},
// MT9P006
{.
name
=
"mt9f002"
,
.
type
=
1
,
.
code
=
SENSOR_MT9F002
},
// MT9F002
{.
name
=
"ibis51300"
,
.
type
=
1
,
.
code
=
SENSOR_IBIS51300
},
// FillFactory IBIS51300
{.
name
=
"kai11002"
,
.
type
=
1
,
.
code
=
SENSOR_KAI11000
},
// Kodak KAI11002
{.
name
=
NULL
,
.
type
=
0
,
.
code
=
0
}
// end of list
};
//#define DETECT_SENSOR 1 ///< Include sensors, May be OR-ed when looking for sensor/multiplexer code/name
//#define DETECT_MUX 2 ///< Include multiplexers, May be OR-ed when looking for sensor/multiplexer code/name
/** Get sensor/multiplexer code (SENSOR_*) by name */
int
get_code_by_name
(
const
char
*
name
,
///< sensor name
int
type
)
///< valid type [DETECT_SENSOR]|[DETECT_MUX]
///< @return sensor code or -EINVAL for invalid name
{
int
i
;
if
(
name
)
for
(
i
=
0
;
sensor_names
[
i
].
name
;
i
++
){
if
((
sensor_names
[
i
].
type
&
type
)
&&
(
!
strncmp
(
sensor_names
[
i
].
name
,
name
,
80
))){
return
sensor_names
[
i
].
code
;
}
}
return
-
EINVAL
;
}
/** Get sensor/multiplexer name (SENSOR_*) by code */
const
char
*
get_name_by_code
(
int
code
,
///< sensor code
int
type
)
///< valid type [DETECT_SENSOR]|[DETECT_MUX]
///< @return sensor name or NULL for invalid code
{
int
i
;
for
(
i
=
0
;
sensor_names
[
i
].
name
;
i
++
){
if
((
sensor_names
[
i
].
type
&
type
)
&&
(
sensor_names
[
i
].
code
==
code
)){
return
sensor_names
[
i
].
name
;
}
}
return
NULL
;
}
/** Get sensor port multiplexer type */
int
get_detected_mux_code
(
int
port
)
///< Sensor port number (0..3)
///< @return port multiplexer code (SENSOR_DETECT, SENSOR_MUX_10359 or SENSOR_NONE)
{
return
sensorPortConfig
[
port
&
3
].
mux
;
}
/** Get sensor type */
int
get_detected_sensor_code
(
int
port
,
///< Sensor port number (0..3)
int
sub_chn
)
///< Sensor subchannel (0..3)
///< @return sensor code (SENSOR_DETECT, SENSOR_NONE, or SENSOR_*)
{
return
sensorPortConfig
[
port
&
3
].
sensor
[
sub_chn
&
3
];
}
/** Set sensor port multiplexer type */
int
set_detected_mux_code
(
int
port
,
///< Sensor port number (0..3)
int
mux_type
)
///< Sensor multiplexer type (SENSOR_DETECT, SENSOR_MUX_10359 or SENSOR_NONE)
///< @return 0 - OK, -EINVAL if mux_type is invalid
{
if
(
mux_type
<
0
)
return
mux_type
;
if
(
!
get_name_by_code
(
mux_type
,
DETECT_MUX
)){
pr_err
(
"%s: Invalid port multiplexer code for port %d: 0x%x
\n
"
,
__func__
,
port
,
mux_type
);
return
-
EINVAL
;
}
sensorPortConfig
[
port
&
3
].
mux
=
mux_type
;
return
0
;
}
/** Set sensor port multiplexer type */
int
set_detected_sensor_code
(
int
port
,
///< Sensor port number (0..3)
int
sub_chn
,
///< Sensor subchannel (0..3)
int
sens_type
)
///< Sensor code (SENSOR_DETECT, SENSOR_NONE, or SENSOR_*)
///< @return 0 - OK, -EINVAL if mux_type is invalid)
{
if
(
sens_type
<
0
)
return
sens_type
;
if
(
!
get_name_by_code
(
sens_type
,
DETECT_SENSOR
)){
pr_err
(
"%s: Invalid sensor code for port %d, subchannel %d: 0x%x
\n
"
,
__func__
,
port
,
sens_type
);
return
-
EINVAL
;
}
sensorPortConfig
[
port
&
3
].
sensor
[
sub_chn
]
=
sens_type
;
return
0
;
}
// SysFS interface to read/modify video memory map
#define SYSFS_PERMISSIONS 0644
/* default permissions for sysfs files */
#define SYSFS_READONLY 0444
#define SYSFS_WRITEONLY 0222
/** Sysfs helper function - get channel number from the last character of the attribute name*/
static
int
get_channel_from_name
(
struct
device_attribute
*
attr
)
///< Linux kernel interface for exporting device attributes
///< @return channel number
{
int
reg
=
0
;
sscanf
(
attr
->
attr
.
name
+
(
strlen
(
attr
->
attr
.
name
)
-
1
),
"%du"
,
&
reg
);
return
reg
;
}
/** Sysfs helper function - get channel and sub-channel numbers from the last 2 characters of the attribute name*/
static
int
get_channel_sub_from_name
(
struct
device_attribute
*
attr
)
///< Linux kernel interface for exporting device attributes
///< @return channel * 16 + sub_channel
{
int
reg
=
0
;
sscanf
(
attr
->
attr
.
name
+
(
strlen
(
attr
->
attr
.
name
)
-
2
),
"%du"
,
&
reg
);
reg
+=
(
reg
/
10
)
*
6
;
return
reg
;
}
static
ssize_t
show_port_mux
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
int
i
;
const
char
*
name
=
get_name_by_code
(
sensorPortConfig
[
get_channel_from_name
(
attr
)].
mux
,
DETECT_MUX
);
if
(
name
)
return
sprintf
(
buf
,
"%s
\n
"
,
name
);
// Should never get here
return
sprintf
(
buf
,
"0x%x
\n
"
,
sensorPortConfig
[
get_channel_from_name
(
attr
)].
mux
);
}
static
ssize_t
show_sensor
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
int
i
;
int
psch
=
get_channel_sub_from_name
(
attr
);
int
port
=
(
psch
>>
4
)
&
3
;
int
sub_chn
=
psch
&
3
;
const
char
*
name
=
get_name_by_code
(
sensorPortConfig
[
port
].
sensor
[
sub_chn
],
DETECT_SENSOR
);
if
(
name
)
return
sprintf
(
buf
,
"%s
\n
"
,
name
);
// Should never get here
return
sprintf
(
buf
,
"0x%x
\n
"
,
sensorPortConfig
[(
psch
>>
4
)
&
3
].
sensor
[
psch
&
3
]);
}
static
ssize_t
store_port_mux
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
const
char
*
buf
,
size_t
count
)
{
size_t
len
;
char
name
[
80
];
int
port
=
get_channel_from_name
(
attr
);
int
i
,
code
,
rslt
;
if
(
sscanf
(
buf
,
"%79s"
,
name
,
&
len
)){
if
((
rslt
=
set_detected_mux_code
(
port
,
get_code_by_name
(
name
,
DETECT_MUX
)))
<
0
)
return
rslt
;
}
return
count
;
}
static
ssize_t
store_sensor
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
const
char
*
buf
,
size_t
count
)
{
size_t
len
;
char
name
[
80
];
int
psch
=
get_channel_sub_from_name
(
attr
);
int
port
=
(
psch
>>
4
)
&
3
;
int
sub_chn
=
psch
&
3
;
int
i
,
rslt
;
if
(
sscanf
(
buf
,
"%79s"
,
name
,
&
len
)){
if
((
rslt
=
set_detected_sensor_code
(
port
,
sub_chn
,
get_code_by_name
(
name
,
DETECT_SENSOR
)))
<
0
)
return
rslt
;
}
return
count
;
}
static
DEVICE_ATTR
(
port_mux0
,
SYSFS_PERMISSIONS
,
show_port_mux
,
store_port_mux
);
static
DEVICE_ATTR
(
port_mux1
,
SYSFS_PERMISSIONS
,
show_port_mux
,
store_port_mux
);
static
DEVICE_ATTR
(
port_mux2
,
SYSFS_PERMISSIONS
,
show_port_mux
,
store_port_mux
);
static
DEVICE_ATTR
(
port_mux3
,
SYSFS_PERMISSIONS
,
show_port_mux
,
store_port_mux
);
static
DEVICE_ATTR
(
sensor00
,
SYSFS_PERMISSIONS
,
show_sensor
,
store_sensor
);
static
DEVICE_ATTR
(
sensor01
,
SYSFS_PERMISSIONS
,
show_sensor
,
store_sensor
);
static
DEVICE_ATTR
(
sensor02
,
SYSFS_PERMISSIONS
,
show_sensor
,
store_sensor
);
static
DEVICE_ATTR
(
sensor03
,
SYSFS_PERMISSIONS
,
show_sensor
,
store_sensor
);
static
DEVICE_ATTR
(
sensor10
,
SYSFS_PERMISSIONS
,
show_sensor
,
store_sensor
);
static
DEVICE_ATTR
(
sensor11
,
SYSFS_PERMISSIONS
,
show_sensor
,
store_sensor
);
static
DEVICE_ATTR
(
sensor12
,
SYSFS_PERMISSIONS
,
show_sensor
,
store_sensor
);
static
DEVICE_ATTR
(
sensor13
,
SYSFS_PERMISSIONS
,
show_sensor
,
store_sensor
);
static
DEVICE_ATTR
(
sensor20
,
SYSFS_PERMISSIONS
,
show_sensor
,
store_sensor
);
static
DEVICE_ATTR
(
sensor21
,
SYSFS_PERMISSIONS
,
show_sensor
,
store_sensor
);
static
DEVICE_ATTR
(
sensor22
,
SYSFS_PERMISSIONS
,
show_sensor
,
store_sensor
);
static
DEVICE_ATTR
(
sensor23
,
SYSFS_PERMISSIONS
,
show_sensor
,
store_sensor
);
static
DEVICE_ATTR
(
sensor30
,
SYSFS_PERMISSIONS
,
show_sensor
,
store_sensor
);
static
DEVICE_ATTR
(
sensor31
,
SYSFS_PERMISSIONS
,
show_sensor
,
store_sensor
);
static
DEVICE_ATTR
(
sensor32
,
SYSFS_PERMISSIONS
,
show_sensor
,
store_sensor
);
static
DEVICE_ATTR
(
sensor33
,
SYSFS_PERMISSIONS
,
show_sensor
,
store_sensor
);
static
struct
attribute
*
root_dev_attrs
[]
=
{
&
dev_attr_port_mux0
.
attr
,
&
dev_attr_port_mux1
.
attr
,
&
dev_attr_port_mux2
.
attr
,
&
dev_attr_port_mux3
.
attr
,
&
dev_attr_sensor00
.
attr
,
&
dev_attr_sensor01
.
attr
,
&
dev_attr_sensor02
.
attr
,
&
dev_attr_sensor03
.
attr
,
&
dev_attr_sensor10
.
attr
,
&
dev_attr_sensor11
.
attr
,
&
dev_attr_sensor12
.
attr
,
&
dev_attr_sensor13
.
attr
,
&
dev_attr_sensor20
.
attr
,
&
dev_attr_sensor21
.
attr
,
&
dev_attr_sensor22
.
attr
,
&
dev_attr_sensor23
.
attr
,
&
dev_attr_sensor30
.
attr
,
&
dev_attr_sensor31
.
attr
,
&
dev_attr_sensor32
.
attr
,
&
dev_attr_sensor33
.
attr
,
NULL
};
static
const
struct
attribute_group
dev_attr_root_group
=
{
.
attrs
=
root_dev_attrs
,
.
name
=
NULL
,
};
static
int
elphel393_detect_sensors_sysfs_register
(
struct
platform_device
*
pdev
)
{
int
retval
=
0
;
struct
device
*
dev
=
&
pdev
->
dev
;
if
(
&
dev
->
kobj
)
{
if
(((
retval
=
sysfs_create_group
(
&
dev
->
kobj
,
&
dev_attr_root_group
)))
<
0
)
return
retval
;
}
return
retval
;
}
/** Initialize this driver from the Device Tree.
* Read per-port multiplexers and sensors. */
static
void
detect_sensors_init_of
(
struct
platform_device
*
pdev
)
///< Platform device structure for this driver
///< @return 0 on success, or negative error.
{
const
char
*
config_string
;
// struct x393_i2c_device_list * dl;
char
names
[
4
][
80
];
// int rslt;
// int num_devs, nd, ni, sa7, num_addr, num_data, khz;
struct
device_node
*
node
=
pdev
->
dev
.
of_node
;
// struct device_attribute *new_attr;
// struct device *dev =&pdev->dev;
int
num_ports
,
port
,
num_sub
,
sub_chn
;
if
(
node
)
{
if
(
num_ports
>
SENSOR_PORTS
)
num_ports
=
SENSOR_PORTS
;
config_string
=
of_get_property
(
node
,
OF_PREFIX_NAME
",ports"
,
NULL
);
// &len);
num_ports
=
sscanf
(
config_string
,
"%79s %79s %79s %79s"
,
names
[
0
],
names
[
1
],
names
[
2
],
names
[
3
]);
for
(
port
=
0
;
port
<
num_ports
;
port
++
){
set_detected_mux_code
(
port
,
get_code_by_name
(
names
[
sub_chn
],
DETECT_MUX
));
}
num_ports
=
of_property_count_strings
(
node
,
OF_PREFIX_NAME
",sensors"
);
for
(
port
=
0
;
port
<
num_ports
;
port
++
){
if
(
of_property_read_string_index
(
node
,
OF_PREFIX_NAME
",sensors"
,
port
,
&
config_string
))
{
pr_err
(
"%s: No data for selected port
\n
"
,
__func__
);
BUG
();
}
num_sub
=
sscanf
(
config_string
,
"%79s %79s %79s %79s"
,
names
[
0
],
names
[
1
],
names
[
2
],
names
[
3
]);
for
(
sub_chn
=
0
;
sub_chn
<
num_sub
;
sub_chn
++
){
set_detected_sensor_code
(
port
,
sub_chn
,
get_code_by_name
(
names
[
sub_chn
],
DETECT_SENSOR
));
}
}
}
}
static
int
detect_sensors_probe
(
struct
platform_device
*
pdev
)
{
unsigned
int
irq
;
int
res
;
struct
device
*
dev
=
&
pdev
->
dev
;
const
struct
of_device_id
*
match
;
const
__be32
*
bufsize_be
;
struct
device_node
*
node
;
// pSensorPortConfig = sensorPortConfig;
elphel393_detect_sensors_sysfs_register
(
pdev
);
match
=
of_match_device
(
elphel393_detect_sensors_of_match
,
dev
);
if
(
!
match
)
pr_err
(
"Detect sensors ERROR: No device tree for '%s' node found
\n
"
,
elphel393_detect_sensors_of_match
[
0
].
compatible
);
return
-
EINVAL
;
detect_sensors_init_of
(
pdev
);
// dev_dbg(dev, "Registering character device with name "DETECT_SENSORS_DRIVER_NAME);
// res = register_chrdev(DETECT_SENSORS_MAJOR, DETECT_SENSORS_DRIVER_NAME, &detect_sensors_fops);
// if(res < 0) {
// dev_err(dev, "\nlogger_init: couldn't get a major number %d.\n ",DETECT_SENSORS_MAJOR);
// return res;
// }
g_dev_ptr
=
dev
;
// for debugfs
return
0
;
}
/** IMU/GPS logger driver remove function */
static
int
detect_sensors_remove
(
struct
platform_device
*
pdev
)
///< [in] pointer to @e platform_device structure
///< @return always 0
{
// unregister_chrdev(DETECT_SENSORS_MAJOR, DETECT_SENSORS_DRIVER_NAME);
return
0
;
}
static
const
struct
of_device_id
elphel393_detect_sensors_of_match
[]
=
{
{
.
compatible
=
"elphel,elphel393-detect_sensors-1.00"
},
{
/* end of list */
}
};
MODULE_DEVICE_TABLE
(
of
,
elphel393_detect_sensors_of_match
);
static
struct
platform_driver
elphel393_detect_sensors
=
{
.
probe
=
detect_sensors_probe
,
.
remove
=
detect_sensors_remove
,
.
driver
=
{
.
name
=
DETECT_SENSORS_DRIVER_NAME
,
.
of_match_table
=
elphel393_detect_sensors_of_match
,
},
};
module_platform_driver
(
elphel393_detect_sensors
);
MODULE_LICENSE
(
"GPL"
);
MODULE_AUTHOR
(
"Andrey Filippov <andrey@elphel.com>."
);
MODULE_DESCRIPTION
(
DETECT_SENSORS_MODULE_DESCRIPTION
);
src/drivers/elphel/detect_sensors.h
0 → 100644
View file @
804b8db1
/***************************************************************************//**
* @file detect_sensors.h
* @brief Determine sensor boards attached to each of the ports. Use
* Device Tree, sysfs to set sensor types per port. Add autodetection
* (using pullup/pull downs) later
* @copyright Copyright 2016 (C) Elphel, Inc.
* @par <b>License</b>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/
#define DETECT_SENSOR 1 ///< Include sensors, May be OR-ed when looking for sensor/multiplexer code/name
#define DETECT_MUX 2 ///< Include multiplexers, May be OR-ed when looking for sensor/multiplexer code/name
int
get_code_by_name
(
const
char
*
name
,
int
type
);
const
char
*
get_name_by_code
(
int
code
,
int
type
);
int
get_detected_mux_code
(
int
port
);
int
get_detected_sensor_code
(
int
port
,
int
sub_chn
);
int
set_detected_mux_code
(
int
port
,
int
mux_type
);
int
set_detected_sensor_code
(
int
port
,
int
sub_chn
,
int
mux_type
);
src/drivers/elphel/pgm_functions.c
View file @
804b8db1
...
...
@@ -210,10 +210,17 @@
#include "pgm_functions.h"
#include "jpeghead.h" // to program FPGA Huffman tables
#include "x393.h"
#include "legacy_defines.h" // temporarily
//
#include "legacy_defines.h" // temporarily
#include "sensor_i2c.h"
#include "x393_videomem.h"
#define COLOR_MARGINS 2 // add this many pixels each side
#define X313_TIMESTAMPLEN 28 // pixels used for timestamp (in linescan mode added after the line)
#define X393_TILEHOR 16
#define X393_TILEVERT 16
#define X393_MAXWIDTH 65536 // 4096 // multiple of 128
#define X393_MAXHEIGHT 65536 // 16384 // multiple of 16 - unsafe - not enough room for black level subtraction
#define X393_MAXHEIGHT_SAFE 65536 // 4096 // multiple of 16 OK for black level subtraction TODO: disable black level if unsafe
/**
* @brief optional debug output macros
...
...
@@ -356,7 +363,10 @@ int pgm_detectsensor (int sensor_port, ///< sensor port number (
if
(
thispars
->
pars
[
P_SENSOR
])
return
0
;
// Sensor is already detected - do not bother (to re-detect it P_SENSOR should be set to 0)
// no other initializations, just the sensor-related stuff (starting with lowest sensor clock)
// stop hardware i2c controller, so it will not get stuck when waiting for !busy
#ifndef NC353
// NC393 - nothing to do here - use a separate module for sensor setup: DT, sysfs, something else (add pin pullup/down)
return
0
;
#else
// NOTE: disabling interrupts here !!!
camera_interrupts
(
0
);
...
...
@@ -376,13 +386,11 @@ int pgm_detectsensor (int sensor_port, ///< sensor port number (
// Need to set slow clock
// f1=imageParamsR[P_CLK_SENSOR]=20000000; setClockFreq(1, imageParamsR[P_CLK_SENSOR]); X3X3_RSTSENSDCM;
#ifdef NC353
was_sensor_freq
=
getClockFreq
(
1
);
// using clock driver data, not thispars
setFramePar
(
sensor_port
,
thispars
,
P_CLK_FPGA
,
getClockFreq
(
0
));
// just in case - read the actual fpga clock frequency and store it (no actions)
setFramePar
(
sensor_port
,
thispars
,
P_CLK_SENSOR
,
48000000
);
setClockFreq
(
1
,
thispars
->
pars
[
P_CLK_SENSOR
]);
printk
(
"
\n
sensor clock set to %d
\n
"
,(
int
)
thispars
->
pars
[
P_CLK_SENSOR
]);
#endif
udelay
(
100
);
// 0.0001 sec to stabilize clocks
X3X3_RSTSENSDCM
;
// FPGA DCM can fail after clock change, needs to be reset
X3X3_SENSDCM_CLK2X_RESET
;
// reset pclk2x DCM also
...
...
@@ -402,12 +410,11 @@ int pgm_detectsensor (int sensor_port, ///< sensor port number (
printk
(
"removing MRST from the sensor
\n
"
);
CCAM_MRST_OFF
;
}
#ifdef CONFIG_ETRAX_ELPHEL_MT9X001
if
(
thispars
->
pars
[
P_SENSOR
]
==
0
)
{
mt9x001_pgm_detectsensor
(
sensor_port
,
sensor
,
thispars
,
prevpars
,
frame16
);
// try Micron 5.0 Mpixel - should return sensor type
printk
(
"trying MT9P001
\n
"
);
}
#endif
// temporary - disabling old sensors
#define ENABLE_OLD_SENSORS 1
#ifdef ENABLE_OLD_SENSORS
...
...
@@ -501,8 +508,10 @@ printk ("Inverted MRST\n");
// NOTE: sensor detected - enabling camera interrupts here (actual interrupts will start later)
// Here interrupts are disabled - with camera_interrupts (0) earlier in this function)
camera_interrupts
(
1
);
return
0
;
#endif
}
...
...
@@ -884,9 +893,9 @@ int pgm_window_common (int sensor_port, ///< sensor port number (
if
((
!
oversize
)
&&
(
width
>
sensor_width
))
width
=
sensor_width
;
// make width to be multiple of the compressor tile (before adding margins of 4 pixels)
width
=
(((
width
/
dh
)
+
timestamp_len
)
/
X3
13_TILEHOR
)
*
X31
3_TILEHOR
-
timestamp_len
;
// divided by dh
width
=
(((
width
/
dh
)
+
timestamp_len
)
/
X3
93_TILEHOR
)
*
X39
3_TILEHOR
-
timestamp_len
;
// divided by dh
// suppose minimal width refers to decimated output
while
(
width
<
sensor
->
minWidth
)
width
+=
X3
1
3_TILEHOR
;
while
(
width
<
sensor
->
minWidth
)
width
+=
X3
9
3_TILEHOR
;
if
(
unlikely
(
thispars
->
pars
[
P_ACTUAL_WIDTH
]
!=
(
width
+
timestamp_len
)))
{
SETFRAMEPARS_SET
(
P_ACTUAL_WIDTH
,
width
+
timestamp_len
);
///full width for the compressor, including timestamp, but excluding margins
}
...
...
@@ -902,7 +911,7 @@ int pgm_window_common (int sensor_port, ///< sensor port number (
if
(
pfh
>
0
)
{
if
(
pfh
<
sensor
->
minHeight
)
pfh
=
sensor
->
minHeight
;
if
(
pfh
&
1
)
pfh
++
;
if
(
height
>
X3
13_MAXHEIGHT
*
dv
)
height
=
X31
3_MAXHEIGHT
*
dv
;
if
(
height
>
X3
93_MAXHEIGHT
*
dv
)
height
=
X39
3_MAXHEIGHT
*
dv
;
pf_stripes
=
height
/
(
pfh
*
dv
);
if
(
pf_stripes
<
1
)
pf_stripes
=
1
;
if
(
unlikely
(
thispars
->
pars
[
P_SENSOR_PIXV
]
!=
pfh
))
{
...
...
@@ -911,9 +920,9 @@ int pgm_window_common (int sensor_port, ///< sensor port number (
}
}
else
{
if
((
!
oversize
)
&&
(
height
>
sensor_height
))
height
=
sensor_height
;
height
=
((
height
/
dv
)
/
X3
13_TILEVERT
)
*
X31
3_TILEVERT
;
// divided by dv (before multisensor options)
height
=
((
height
/
dv
)
/
X3
93_TILEVERT
)
*
X39
3_TILEVERT
;
// divided by dv (before multisensor options)
// suppose minimal height refers to decimated output
while
(
height
<
sensor
->
minHeight
)
height
+=
X3
1
3_TILEVERT
;
while
(
height
<
sensor
->
minHeight
)
height
+=
X3
9
3_TILEVERT
;
if
(
unlikely
(
thispars
->
pars
[
P_SENSOR_PIXV
]
!=
height
+
(
2
*
COLOR_MARGINS
)))
SETFRAMEPARS_SET
(
P_SENSOR_PIXV
,
height
+
(
2
*
COLOR_MARGINS
));
///full height for the sensor (after decimation), including margins
height
*=
dv
;
...
...
src/drivers/elphel/pgm_functions.h
View file @
804b8db1
//pgm_functions.h
///extern struct sensorproc_t * sensorproc;
/***************************************************************************//**
* @file pgm_functions.h
* @brief Sensor/FPGA programming functions, called from IRQ/tasklet in
* response to the parameter changes
* @copyright Copyright 2008-2016 (C) Elphel, Inc.
* @par <b>License</b>
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/
#include "sensor_i2c.h"
...
...
src/drivers/elphel/x393_videomem.c
View file @
804b8db1
...
...
@@ -497,9 +497,9 @@ static int videomem_probe(struct platform_device *pdev)
dev_dbg
(
dev
,
"Registering character device with name "
VIDEOMEM_DRIVER_NAME
);
res
=
register_chrdev
(
LOGGER
_MAJOR
,
VIDEOMEM_DRIVER_NAME
,
&
videomem_fops
);
res
=
register_chrdev
(
VIDEOMEM
_MAJOR
,
VIDEOMEM_DRIVER_NAME
,
&
videomem_fops
);
if
(
res
<
0
)
{
dev_err
(
dev
,
"
\
n
logger_init
: couldn't get a major number %d.
\n
"
,
VIDEOMEM_MAJOR
);
dev_err
(
dev
,
"
\
v
ideomem_probe
: couldn't get a major number %d.
\n
"
,
VIDEOMEM_MAJOR
);
return
res
;
}
// Setup interrupt
...
...
@@ -513,13 +513,13 @@ static int videomem_probe(struct platform_device *pdev)
dev_err
(
dev
,
"can not allocate interrupts for %s
\n
"
,
"membridge_irq"
);
return
-
EBUSY
;
}
init_waitqueue_head
(
&
videomem_wait_queue
);
// wait queue for
logg
er
init_waitqueue_head
(
&
videomem_wait_queue
);
// wait queue for
video memory driv
er
g_dev_ptr
=
dev
;
// for debugfs
return
0
;
}
/**
IMU/GPS logger
driver remove function */
/**
Video memory
driver remove function */
static
int
videomem_remove
(
struct
platform_device
*
pdev
)
///< [in] pointer to @e platform_device structure
///< @return always 0
{
...
...
src/include/elphel/c313a.h
View file @
804b8db1
...
...
@@ -224,15 +224,22 @@
// leave it here - may be used in user applications
#define SENSOR_MASK 0xfc ///< Mask to apply for distinguish between different sensor groups (of similar devices)
#define SENSOR_DETECT 0x00 ///< Unknown sensor, try to autodetect
#define SENSOR_ZR32112 0x04 ///< Zoran ZR32112
#define SENSOR_ZR32212 0x08 ///< Zoran ZR32212
#define SENSOR_KAC1310 0x20 ///< Kodak KAC1310
#define SENSOR_KAC5000 0x24 ///< Kodak KAC5000
#define SENSOR_MI1300 0x30 ///< Micron MI1300
#define SENSOR_MT9X001 0x30 ///< Micron: MT9M001 - 31, MT9D001 - 32, MT9T001 - 33, MT9P001 - 34
#define SENSOR_MT9Y001 0x34 ///< Micron/Aptina/Onsemi MT9P001 - 34
#define SENSOR_MT9M001 0x31 ///< MT9M001
#define SENSOR_MT9D001 0x32 ///< MT9D001
#define SENSOR_MT9T001 0x33 ///< MT9T001
#define SENSOR_MT9P006 0x34 ///< MT9P006
#define SENSOR_MT9F002 0x38 ///< MT9F002
//#define SENSOR_MT9Y001 0x34 ///< Micron/Aptina/Onsemi MT9P001 - 34
#define SENSOR_IBIS51300 0x40 ///< FillFactory IBIS51300
#define SENSOR_KAI11000 0x80 ///< Kodak KAI11002
#define SENSOR_MUX_10359 0xe0 ///< Sensor multiplexer 10359
#define SENSOR_NONE 0xfc ///< No sensor present
// sensor sizes:
...
...
src/include/elphel/driver_numbers.h
View file @
804b8db1
...
...
@@ -19,6 +19,7 @@
#define IMAGEACQ_MAJOR 140
#define LOGGER_MAJOR 141
#define VIDEOMEM_MAJOR 142 // implement raw access to memory and/or 16-bit image buffers over membridge interface
#define DETECT_SENSORS_MAJOR 143 // Maybe not needed?
/// MINORS
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment