#include <linux/module.h>
#include <linux/mm.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/autoconf.h>
#include <linux/vmalloc.h>
#include <asm/system.h>
#include <asm/byteorder.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/delay.h>
#include <asm/uaccess.h>
#include <asm/elphel/driver_numbers.h>
#include <asm/elphel/c313a.h>
#include <asm/elphel/exifa.h>
#include "fpgactrl.h"
#include "framepars.h"
#include "gamma_tables.h"
Include dependency graph for gamma_tables.c:
Go to the source code of this file.
Data Structures | |
struct | gammas_pd |
to use with mmap More... | |
Defines | |
#define | MDF(x) |
optional debug output | |
#define | D10(x) |
#define | D1I(x) x |
#define | MDF10(x) |
#define | MDF11(x) |
#define | X3X3_GAMMAS_DRIVER_NAME "Elphel (R) Model 353 Gamma Tables device driver" |
#define | GAMMA_THRESH (GAMMA_CACHE_NUMBER/16) |
number of different non-scaled tables in cache when it starts to overwrite non-scaled tables rather than scaled TODO: use P_*? | |
#define | GAMMA_FILE_SIZE GAMMA_CACHE_NUMBER |
File size reported by gamma device driver. | |
Functions | |
static struct gamma_stuct_t gammas[GAMMA_CACHE_NUMBER] | __attribute__ ((aligned(PAGE_SIZE))) |
int | gammas_open (struct inode *inode, struct file *file) |
Gammas driver OPEN method. | |
int | gammas_release (struct inode *inode, struct file *file) |
Gammas driver RELEASE method. | |
loff_t | gammas_lseek (struct file *file, loff_t offset, int orig) |
Gammas driver LSEEK method (and execute commands)
| |
ssize_t | gammas_write (struct file *file, const char *buf, size_t count, loff_t *off) |
Gammas driver WRITE method write should be a single call (with or without actual table), file pointer after write is result node index (0 - failure) write method receives data and uses it with set_gamma_table()
| |
int | gammas_mmap (struct file *file, struct vm_area_struct *vma) |
Gammas driver MMAP method (debug feature that gives access to gammas structures, should be used read only). | |
static int __init | gammas_init (void) |
Gammas driver init. | |
void | remove_from_nonscaled (int index) |
remove item from non-scaled (top, "horizontal") chain | |
void | remove_from_scaled (int index) |
remove item from scaled ("vertical") chain | |
void | remove_from_all (int index) |
remove item from the all ("diagonal") chain | |
void | insert_first_nonscaled (int index) |
insert item into non-scaled ("horizontal") chain as first | |
void | insert_first_scaled (int non_scaled, int index) |
insert item into scaled ("vertical") chain as first | |
void | insert_first_all (int index) |
insert item into "all" ("diagonal") chain as first | |
void | init_gammas (void) |
Initialize gamma tables data structures. | |
int | is_gamma_current (unsigned short hash16, unsigned short scale, int index) |
verifies that index is current (points to specified hash and scale) | |
int | is_gamma_valid (unsigned short hash16, unsigned short scale, int index) |
verifies that index is current and points to a valid table with specified hash and scale | |
unsigned long | get_locked_hash32 (int color) |
Looks for the hash32 last programmed to the FPGA for the particular color. | |
void | lock_gamma_node (int index, int color) |
Lock gamma table for the specified color, save previous locks (if any) so new locks can be applied/canceled NOTE: interrupts should be disabled ***. | |
int | unlock_gamma_node (int color) |
Unlock gamma table for the specified color NOTE: Not needed anymore. | |
unsigned long * | get_gamma_fpga (int color) |
Find a gamma table in FPGA format to be programmed (table should already be locked for this color). | |
int | gamma_new_node (void) |
Get a new node for gamma tables Find least recently used node (balancing between non-scaled and scaled), remove it from current chains and return pointers in the returned node are not initialized, "valid" bit is cleared NOTE: interrupts should be disabled ***. | |
void | gamma_encode_fpga (unsigned short *gamma_in, unsigned long *gamma_out) |
Hardware-dependent encoding of the FPGA "gamma" table. | |
void | gamma_calc_scaled (unsigned short scale, unsigned short *gamma_in, unsigned short *gamma_out) |
Hardware-dependent encoding of the FPGA "gamma" table. Converts unsigned short array of 257 16-bit values (only 10 msb-s are used) to 256 unsigned long words to be written to FPGA. | |
void | gamma_calc_reverse (unsigned short *gamma_in, unsigned char *gamma_out) |
scale gamma table by (scale>>GAMMA_SCALE_SHIFT), saturate to 0..0xffff | |
int | set_gamma_table (unsigned short hash16, unsigned short scale, unsigned short *gamma_proto, unsigned char mode, int color) |
calculate gamma table (and requested derivatives), insert new node if needed. | |
module_init (gammas_init) | |
MODULE_LICENSE ("GPLv3.0") | |
MODULE_AUTHOR ("Andrey Filippov <andrey@elphel.com>.") | |
MODULE_DESCRIPTION (X3X3_GAMMAS_DRIVER_NAME) | |
Variables | |
gamma_stuct_t * | gammas_p |
static struct file_operations | gammas_fops |
#define D10 | ( | x | ) |
Definition at line 146 of file gamma_tables.c.
#define GAMMA_FILE_SIZE GAMMA_CACHE_NUMBER |
File size reported by gamma device driver.
Definition at line 686 of file gamma_tables.c.
Referenced by gammas_open().
#define GAMMA_THRESH (GAMMA_CACHE_NUMBER/16) |
number of different non-scaled tables in cache when it starts to overwrite non-scaled tables rather than scaled
TODO: use P_*?
Definition at line 158 of file gamma_tables.c.
Referenced by gamma_new_node().
#define MDF | ( | x | ) |
#define MDF10 | ( | x | ) |
Definition at line 147 of file gamma_tables.c.
Referenced by gammas_init(), gammas_lseek(), gammas_mmap(), gammas_open(), gammas_release(), init_gammas(), and set_gamma_table().
#define MDF11 | ( | x | ) |
Definition at line 148 of file gamma_tables.c.
Referenced by gamma_calc_reverse(), gamma_calc_scaled(), gamma_encode_fpga(), get_gamma_fpga(), insert_first_nonscaled(), insert_first_scaled(), and unlock_gamma_node().
#define X3X3_GAMMAS_DRIVER_NAME "Elphel (R) Model 353 Gamma Tables device driver" |
static struct gamma_stuct_t gammas [GAMMA_CACHE_NUMBER] __attribute__ | ( | (aligned(PAGE_SIZE)) | ) | [static] |
void gamma_calc_reverse | ( | unsigned short * | gamma_in, | |
unsigned char * | gamma_out | |||
) |
scale gamma table by (scale>>GAMMA_SCALE_SHIFT), saturate to 0..0xffff
gamma_in | direct gamma table (16 bit) | |
gamma_out | reversed gamma table (8 bit) |
running value to be compared against direct gamma
current value of reverse gamma table
current indedx of reverse gamma table
Definition at line 444 of file gamma_tables.c.
References MDF11, printk, and x.
Referenced by set_gamma_table().
void gamma_calc_scaled | ( | unsigned short | scale, | |
unsigned short * | gamma_in, | |||
unsigned short * | gamma_out | |||
) |
Hardware-dependent encoding of the FPGA "gamma" table. Converts unsigned short array of 257 16-bit values (only 10 msb-s are used) to 256 unsigned long words to be written to FPGA.
scale | scale to apply (1.0 ~ GAMMA_SCLALE_1=0x400) | |
gamma_in | input (non-scaled) gamma table (16 bit) | |
gamma_out | output (scaled) gamma table (16 bit) |
rounding, not truncating
Definition at line 424 of file gamma_tables.c.
References d, GAMMA_SCALE_SHIFT, MDF11, and printk.
Referenced by set_gamma_table().
void gamma_encode_fpga | ( | unsigned short * | gamma_in, | |
unsigned long * | gamma_out | |||
) |
Hardware-dependent encoding of the FPGA "gamma" table.
gamma_in | pointer to array of 257 16-bit values (only 10 msb-s are currently used) | |
gamma_out | pointer to an array of 256 unsigned long words to be written to FPGA |
Definition at line 402 of file gamma_tables.c.
Referenced by set_gamma_table().
int gamma_new_node | ( | void | ) |
Get a new node for gamma tables Find least recently used node (balancing between non-scaled and scaled), remove it from current chains and return pointers in the returned node are not initialized, "valid" bit is cleared NOTE: interrupts should be disabled ***.
no scaled for the oldest hash
sacrifice oldest hash
use oldest scaled
skip locked if any (should be unlikely to get any locked)
remove from "all" chain (should work for tmp_p being oldest or not
remove from "scaled chain"
Definition at line 377 of file gamma_tables.c.
References GAMMA_THRESH, gamma_stuct_t::newer_all, gamma_stuct_t::oldest_all, gamma_stuct_t::oldest_non_scaled, remove_from_all(), remove_from_nonscaled(), remove_from_scaled(), and gamma_stuct_t::valid.
Referenced by set_gamma_table().
static int __init gammas_init | ( | void | ) | [static] |
Gammas driver init.
maybe not needed to put linear to cache - it can be calculated as soon FPGA will be tried to be programmed with
hash16==0
Definition at line 883 of file gamma_tables.c.
References ELPHEL_DEBUG_DELAY, GAMMA_SCLALE_1, gammas_fops, GAMMAS_MAJOR, init_gammas(), KERN_ERR, MDF10, printk, set_gamma_table(), udelay, and X3X3_GAMMAS_DRIVER_NAME.
loff_t gammas_lseek | ( | struct file * | file, | |
loff_t | offset, | |||
int | orig | |||
) |
Gammas driver LSEEK method (and execute commands)
file | ||
offset | ||
orig | SEEK_SET, SEEK_CUR or SEEK_SET END |
Execute commands
wrong index
other commands
not SEEK_SET/SEEK_CUR/SEEK_END
switch (orig)
other minors
Definition at line 762 of file gamma_tables.c.
References CMOSCAM_MINOR_GAMMAS, GAMMA_CACHE_NUMBER, gammas_pd::hash16, init_gammas(), is_gamma_current(), LSEEK_GAMMA_INIT, LSEEK_GAMMA_ISCURRENT, MDF10, gammas_pd::minor, printk, gammas_pd::scale, SEEK_CUR, SEEK_END, and SEEK_SET.
int gammas_mmap | ( | struct file * | file, | |
struct vm_area_struct * | vma | |||
) |
Gammas driver MMAP method (debug feature that gives access to gammas structures, should be used read only).
file | ||
vma |
Definition at line 861 of file gamma_tables.c.
References CMOSCAM_MINOR_GAMMAS, gammas_p, MDF10, gammas_pd::minor, and printk.
int gammas_open | ( | struct inode * | inode, | |
struct file * | file | |||
) |
Gammas driver OPEN method.
inode | inode | |
file | file pointer |
already allocated
Definition at line 701 of file gamma_tables.c.
References CMOSCAM_MINOR_GAMMAS, GAMMA_FILE_SIZE, GFP_KERNEL, gammas_pd::hash16, kfree, kmalloc, MDF10, gammas_pd::minor, mode, printk, and gammas_pd::scale.
int gammas_release | ( | struct inode * | inode, | |
struct file * | file | |||
) |
Gammas driver RELEASE method.
inode | inode | |
file | file pointer |
do not need to free anything - "wrong number"
Definition at line 732 of file gamma_tables.c.
References CMOSCAM_MINOR_GAMMAS, kfree, MDF10, and printk.
ssize_t gammas_write | ( | struct file * | file, | |
const char * | buf, | |||
size_t | count, | |||
loff_t * | off | |||
) |
Gammas driver WRITE method write should be a single call (with or without actual table), file pointer after write is result node index (0 - failure) write method receives data and uses it with set_gamma_table()
file | ||
buf | ||
count | ||
off |
************* NOTE: Never use file->f_pos in write() and read() !!!
complete gamma table is not available
Definition at line 821 of file gamma_tables.c.
References color, gamma, gammas_pd::hash16, mode, and gammas_pd::scale.
unsigned long* get_gamma_fpga | ( | int | color | ) |
Find a gamma table in FPGA format to be programmed (table should already be locked for this color).
color | color index (0..3) of the table |
NOTE: Not needed anymore?
Definition at line 360 of file gamma_tables.c.
References gamma_stuct_t::fpga, gamma_stuct_t::locked_color, MDF11, and printk.
Referenced by pgm_gammaload().
unsigned long get_locked_hash32 | ( | int | color | ) |
Looks for the hash32 last programmed to the FPGA for the particular color.
color |
Definition at line 314 of file gamma_tables.c.
References gamma_stuct_t::hash32, and gamma_stuct_t::locked_color.
Referenced by pgm_gamma(), and pgm_gammaload().
void init_gammas | ( | void | ) |
Initialize gamma tables data structures.
empty 2-d chain
all entries in a same
no parent.FIXME: Where is it used? -1 if never used
something else?
Definition at line 258 of file gamma_tables.c.
References flags, GAMMA_CACHE_NUMBER, gammas_p, local_irq_restore, local_irq_save, gamma_stuct_t::locked, MDF10, gamma_stuct_t::newer_all, gamma_stuct_t::newest_all, gamma_stuct_t::newest_non_scaled, gamma_stuct_t::non_scaled_length, gamma_stuct_t::older_all, gamma_stuct_t::oldest_all, gamma_stuct_t::oldest_non_scaled, printk, and gamma_stuct_t::valid.
Referenced by gammas_init(), and gammas_lseek().
void insert_first_all | ( | int | index | ) | [inline] |
insert item into "all" ("diagonal") chain as first
index | item index to remove |
Definition at line 248 of file gamma_tables.c.
References gamma_stuct_t::newer_all, gamma_stuct_t::newest_all, and gamma_stuct_t::older_all.
Referenced by set_gamma_table().
void insert_first_nonscaled | ( | int | index | ) | [inline] |
insert item into non-scaled ("horizontal") chain as first
index | item index to remove |
no scaled yet - point to itself
no scaled yet - point to itself
Definition at line 214 of file gamma_tables.c.
References MDF11, gamma_stuct_t::newer_non_scaled, gamma_stuct_t::newest_non_scaled, gamma_stuct_t::newest_scaled, gamma_stuct_t::non_scaled_length, gamma_stuct_t::older_non_scaled, gamma_stuct_t::oldest_scaled, printk, and gamma_stuct_t::this_non_scaled.
Referenced by set_gamma_table().
void insert_first_scaled | ( | int | non_scaled, | |
int | index | |||
) | [inline] |
insert item into scaled ("vertical") chain as first
non_scaled | index of non-scaled version of the node | |
index | item index to remove |
Definition at line 232 of file gamma_tables.c.
References MDF11, gamma_stuct_t::newer_scaled, gamma_stuct_t::newest_scaled, gamma_stuct_t::older_scaled, printk, and gamma_stuct_t::this_non_scaled.
Referenced by set_gamma_table().
int is_gamma_current | ( | unsigned short | hash16, | |
unsigned short | scale, | |||
int | index | |||
) |
verifies that index is current (points to specified hash and scale)
hash16 | - 16-bit unique hash for gamma table | |
scale | - 16-bit scale for gamma table (6.10, so GAMMA_SCLALE_10x400 is 1.0) | |
index | - gamma table index |
Definition at line 293 of file gamma_tables.c.
Referenced by gammas_lseek(), and set_gamma_table().
int is_gamma_valid | ( | unsigned short | hash16, | |
unsigned short | scale, | |||
int | index | |||
) |
verifies that index is current and points to a valid table with specified hash and scale
hash16 | - 16-bit unique hash for gamma table | |
scale | - 16-bit scale for gamma table (6.10, so GAMMA_SCLALE_1=0x400 is 1.0) | |
index | - gamma table index |
Definition at line 304 of file gamma_tables.c.
void lock_gamma_node | ( | int | index, | |
int | color | |||
) | [inline] |
Lock gamma table for the specified color, save previous locks (if any) so new locks can be applied/canceled NOTE: interrupts should be disabled ***.
index | gamma table index | |
color |
valid color
new gamma to the same color
remove any previous lock on the same color (if any)
Definition at line 325 of file gamma_tables.c.
References gamma_stuct_t::locked, and gamma_stuct_t::locked_color.
Referenced by set_gamma_table().
MODULE_AUTHOR | ( | "Andrey Filippov <andrey@elphel.com>." | ) |
MODULE_DESCRIPTION | ( | X3X3_GAMMAS_DRIVER_NAME | ) |
module_init | ( | gammas_init | ) |
MODULE_LICENSE | ( | "GPLv3.0" | ) |
void remove_from_all | ( | int | index | ) | [inline] |
remove item from the all ("diagonal") chain
index | item index to remove |
always - in that chain - after init
Definition at line 205 of file gamma_tables.c.
References gamma_stuct_t::newer_all, and gamma_stuct_t::older_all.
Referenced by gamma_new_node(), and set_gamma_table().
void remove_from_nonscaled | ( | int | index | ) | [inline] |
remove item from non-scaled (top, "horizontal") chain
index | item index to remove |
Definition at line 184 of file gamma_tables.c.
References gamma_stuct_t::newer_non_scaled, gamma_stuct_t::non_scaled_length, and gamma_stuct_t::older_non_scaled.
Referenced by gamma_new_node(), and set_gamma_table().
void remove_from_scaled | ( | int | index | ) | [inline] |
remove item from scaled ("vertical") chain
index | item index to remove |
will skip first, untill the cache is all used
Definition at line 194 of file gamma_tables.c.
References gamma_stuct_t::newer_scaled, and gamma_stuct_t::older_scaled.
Referenced by gamma_new_node(), and set_gamma_table().
int set_gamma_table | ( | unsigned short | hash16, | |
unsigned short | scale, | |||
unsigned short * | gamma_proto, | |||
unsigned char | mode, | |||
int | color | |||
) |
calculate gamma table (and requested derivatives), insert new node if needed.
hash16 | 16-bit unique (non-scaled) gamma table identifier. Can be 1-byte gamma and 1-byte black level shift TODO: make black level fine-grained? | |
scale | gamma table scale (currently 0x400 ~ 1.0) GAMMA_SCLALE_1 = 0x400 | |
gamma_proto | 16-bit gamma table prototype (or NULL) | |
mode | bits specify calculation mode:
| |
color | color index (0..3) to lock table for (if mode bit 4 is set), otherwise color is ignored |
NOTE: here
disable interrupts here
look for the matching hash
gammas[0].oldest_all=GAMMA_CACHE_NUMBER-1; gammas[0].newest_all=1;
NOTE: 253
NOTE: never
NOTE: 0xff
Got right hash?
no luck
NOTE: never
NOTE: never
matching hash not found, new table is not provided - return 0;
Create new proto table
could not allocate node
failure: could not allocate node - return 0;
fill it:
points to itself - no scaled versions yet
points to itself - no scaled versions yet
let interrupts to take place, and disable again
check if it is still there (likely so, but allow it to fail).
failure: other code used this node - return 0; (try not_nice next time?)
copy the provided table (full 16 bits)
add it to the chain
matching hash found,make it newest (remove from the chain + add to the chain)
if 0 - it is already the newest
NOTE: 0xff
NOTE: 0xff
NOTE: 0xff
now looking for the correct scale.
wanted non-scaled, got it ///NOTE: returns here
FIXME: 0xff
FIXME: got stuck here
Got right scale?
no luck
create new scale
could not allocate node
failure: could not allocate node - return 0;
fill it
insert into 2-d
insert into 1-d (all)
let interrupts to take place, and disable again
check if it is still there (likely so, but allow it to fail).
failure: other code used this node - return 0; (try not_nice next time?)
scaled table already exists, make it first in 2 chains:
found right scale, make it newest in two chain (2d - hash/scale and 1-d - all scaled together, regardless of the hash 2-d chain
not already the newest of scales for the same hash
1-d chain
not already the newest from all scaled
is the scaled version already calculated?
calculate scaled version
is hardware-encoded array already calculated (do it if not)?
lock the node for the color
let interrupts to take place, and disable again
check if it is still there (likely so, but allow it to fail).
failure: other code used this node - return 0; (try not_nice next time?)
Definition at line 475 of file gamma_tables.c.
References D10, D1I, flags, fpga, gamma_calc_reverse(), gamma_calc_scaled(), gamma_encode_fpga(), GAMMA_FPGA_MASK, GAMMA_MODE_HARDWARE, GAMMA_MODE_LOCK, GAMMA_MODE_NEED_REVERSE, GAMMA_MODE_NOT_NICE, gamma_new_node(), GAMMA_VALID_MASK, GAMMA_VALID_REVERSE, gamma_stuct_t::hash16, insert_first_all(), insert_first_nonscaled(), insert_first_scaled(), is_gamma_current(), local_irq_restore, local_irq_save, lock_gamma_node(), MDF10, memcpy(), gamma_stuct_t::newest_non_scaled, gamma_stuct_t::newest_scaled, gamma_stuct_t::older_non_scaled, gamma_stuct_t::older_scaled, gamma_stuct_t::oldest_scaled, printk, remove_from_all(), remove_from_nonscaled(), remove_from_scaled(), gamma_stuct_t::scale, and gamma_stuct_t::valid.
Referenced by gammas_init(), pgm_gamma(), and pgm_gammaload().
int unlock_gamma_node | ( | int | color | ) |
Unlock gamma table for the specified color NOTE: Not needed anymore.
color | color index (0..3) |
clear appropriate "locked" bit for this table
Definition at line 341 of file gamma_tables.c.
References flags, local_irq_restore, local_irq_save, gamma_stuct_t::locked, gamma_stuct_t::locked_color, MDF11, and printk.
struct file_operations gammas_fops [static] |
Initial value:
{ owner: THIS_MODULE, llseek: gammas_lseek, write: gammas_write, open: gammas_open, mmap: gammas_mmap, release: gammas_release }
Definition at line 687 of file gamma_tables.c.
Referenced by gammas_init().
struct gamma_stuct_t* gammas_p |