Skip to content

Commit

Permalink
Add _stdout character device
Browse files Browse the repository at this point in the history
Bump build rev
  • Loading branch information
Tom Richardson committed Jun 29, 2020
1 parent 3bfb2d8 commit 1f94fb6
Show file tree
Hide file tree
Showing 4 changed files with 229 additions and 46 deletions.
133 changes: 113 additions & 20 deletions availink/avl62x1/avl62x1_top.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ static int bs_min_sr = 1000000;
//-------------------

//---- character device stuff ----
#define DEVICE_NAME "avl62x1_i2c" //device at /dev/DEVICE_NAME
#define CLASS_NAME "avl62x1" //device class
#define I2CCTL_DEVICE_NAME "avl62x1_i2c" //device at /dev/DEVICE_NAME
#define I2CCTL_CLASS_NAME "avl62x1_i2c" //device class
#define I2CCTL_IOC_MAGIC 'k'
#define I2CCTL_IOCLOCK _IO(I2CCTL_IOC_MAGIC, 0)
#define I2CCTL_IOCUNLOCK _IO(I2CCTL_IOC_MAGIC, 1)
Expand Down Expand Up @@ -117,28 +117,28 @@ static struct file_operations i2cctl_fops =

int init_avl62x1_i2cctl_device(struct avl62x1_priv *priv)
{
i2cctl_maj_num = register_chrdev(0, DEVICE_NAME, &i2cctl_fops);
i2cctl_maj_num = register_chrdev(0, I2CCTL_DEVICE_NAME, &i2cctl_fops);
if (i2cctl_maj_num < 0)
{
p_error("failed to register a major number");
return i2cctl_maj_num;
}

// Register the device class
i2cctl_class = class_create(THIS_MODULE, CLASS_NAME);
i2cctl_class = class_create(THIS_MODULE, I2CCTL_CLASS_NAME);
if (IS_ERR(i2cctl_class))
{ // Check for error and clean up if there is
unregister_chrdev(i2cctl_maj_num, DEVICE_NAME);
unregister_chrdev(i2cctl_maj_num, I2CCTL_DEVICE_NAME);
p_error("Failed to register device class");
return PTR_ERR(i2cctl_class); // Correct way to return an error on a pointer
}

// Register the device driver
i2cctl_device = device_create(i2cctl_class, NULL, MKDEV(i2cctl_maj_num, 0), NULL, DEVICE_NAME);
i2cctl_device = device_create(i2cctl_class, NULL, MKDEV(i2cctl_maj_num, 0), NULL, I2CCTL_DEVICE_NAME);
if (IS_ERR(i2cctl_device))
{ // Clean up if there is an error
class_destroy(i2cctl_class); // Repeated code but the alternative is goto statements
unregister_chrdev(i2cctl_maj_num, DEVICE_NAME);
unregister_chrdev(i2cctl_maj_num, I2CCTL_DEVICE_NAME);
p_error("Failed to create the device");
return PTR_ERR(i2cctl_device);
}
Expand All @@ -154,7 +154,7 @@ void deinit_avl62x1_i2cctl_device(struct avl62x1_priv *priv)
device_destroy(i2cctl_class, MKDEV(i2cctl_maj_num, 0)); // remove the device
class_unregister(i2cctl_class); // unregister the device class
class_destroy(i2cctl_class); // remove the device class
unregister_chrdev(i2cctl_maj_num, DEVICE_NAME); // unregister the major number
unregister_chrdev(i2cctl_maj_num, I2CCTL_DEVICE_NAME); // unregister the major number

mutex_unlock(&i2cctl_fe_mutex);
mutex_unlock(&i2cctl_tuneri2c_mutex);
Expand Down Expand Up @@ -253,7 +253,105 @@ static int i2cctl_dev_release(struct inode *inodep, struct file *filep)
mutex_unlock(&i2cctl_dev_mutex);
return 0;
}
//--------------------------------
//--------------------------------------------------------------------------

//-------------- stdout character device -----------------------------------
#if INCLUDE_STDOUT
#include "read_stdout_62x1.c"
#define STDOUT_DEVICE_NAME "avl62x1_stdout"
#define STDOUT_CLASS_NAME "avl62x1_stdout"
static DEFINE_MUTEX(stdout_dev_mutex);
static int stdout_maj_num;
static struct class* stdout_class = NULL;
static struct device* stdout_device = NULL;
static int stdout_dev_open(struct inode *, struct file *);
static int stdout_dev_release(struct inode *, struct file *);
static ssize_t stdout_dev_read(struct file *, char *, size_t, loff_t *);
static struct file_operations stdout_fops =
{
.owner = THIS_MODULE,
.open = stdout_dev_open,
.read = stdout_dev_read,
.release = stdout_dev_release};
int init_avl62x1_stdout_device(struct avl62x1_priv *priv)
{
stdout_maj_num = register_chrdev(0, STDOUT_DEVICE_NAME, &stdout_fops);
if (stdout_maj_num < 0)
{
p_error("failed to register a major number");
return stdout_maj_num;
}

// Register the device class
stdout_class = class_create(THIS_MODULE, STDOUT_CLASS_NAME);
if (IS_ERR(stdout_class))
{ // Check for error and clean up if there is
unregister_chrdev(stdout_maj_num, STDOUT_DEVICE_NAME);
p_error("Failed to register device class");
return PTR_ERR(stdout_class); // Correct way to return an error on a pointer
}

// Register the device driver
stdout_device = device_create(stdout_class, NULL, MKDEV(stdout_maj_num, 0), NULL, STDOUT_DEVICE_NAME);
if (IS_ERR(stdout_device))
{ // Clean up if there is an error
class_destroy(stdout_class); // Repeated code but the alternative is goto statements
unregister_chrdev(stdout_maj_num, STDOUT_DEVICE_NAME);
p_error("Failed to create the device");
return PTR_ERR(stdout_device);
}

mutex_init(&stdout_dev_mutex);
return 0;
}

void deinit_avl62x1_stdout_device(struct avl62x1_priv *priv)
{
device_destroy(stdout_class, MKDEV(stdout_maj_num, 0)); // remove the device
class_unregister(stdout_class); // unregister the device class
class_destroy(stdout_class); // remove the device class
unregister_chrdev(stdout_maj_num, STDOUT_DEVICE_NAME); // unregister the major number

mutex_destroy(&stdout_dev_mutex);
}

static int stdout_dev_open(struct inode *inodep, struct file *filep)
{
p_debug_lvl(4,"");
if (!mutex_trylock(&stdout_dev_mutex))
{ /// Try to acquire the mutex (i.e., put the lock on/down)
/// returns 1 if successful and 0 if there is contention
p_error("Device in use by another process");
return -EBUSY;
}
return 0;
}

static ssize_t stdout_dev_read(
struct file *filep,
char *buffer, /* The buffer to fill with data */
size_t len, /* The length of the buffer */
loff_t *offset) /* Our offset in the file */
{

char *stdout_buf;
char *sp_stdout_buf;
int ttl;
stdout_buf = read_stdout(&global_priv->frontend);
sp_stdout_buf = read_sp_stdout(&global_priv->frontend);
ttl = simple_read_from_buffer(buffer,len,offset,stdout_buf,strlen(stdout_buf));
ttl += simple_read_from_buffer(&buffer[strlen(stdout_buf)],len,offset,sp_stdout_buf,strlen(sp_stdout_buf));
return ttl;
}

static int stdout_dev_release(struct inode *inodep, struct file *filep)
{
p_debug_lvl(4,"");
safe_mutex_unlock(&stdout_dev_mutex);
return 0;
}
#endif
//--------------------------------------------------------------------------

static int diseqc_set_voltage(struct dvb_frontend *fe,
enum fe_sec_voltage voltage);
Expand Down Expand Up @@ -858,10 +956,6 @@ static int get_frontend(struct dvb_frontend *fe,
return ret;
}

#if INCLUDE_STDOUT
#include "read_stdout_62x1.c"
#endif

static int read_status(struct dvb_frontend *fe, enum fe_status *status)
{
int r = AVL_EC_OK;
Expand All @@ -873,13 +967,6 @@ static int read_status(struct dvb_frontend *fe, enum fe_status *status)

p_debug_lvl(10, "");

#if INCLUDE_STDOUT
if (debug > 2)
{
printk("%s", read_stdout(fe));
}
#endif

if (bs_states[demod_id].bs_mode)
{
if (bs_states[demod_id].info.finished)
Expand Down Expand Up @@ -1435,6 +1522,9 @@ static void release_fe(struct dvb_frontend *fe)
struct avl62x1_priv *priv = fe->demodulator_priv;

p_debug("");
#if INCLUDE_STDOUT
deinit_avl62x1_stdout_device(priv);
#endif
deinit_avl62x1_i2cctl_device(priv);
kfree(priv->chip->chip_pub);
kfree(priv->chip->chip_priv);
Expand Down Expand Up @@ -1609,6 +1699,9 @@ struct dvb_frontend *avl62x1_attach(struct avl62x1_config *config,
p_info("Firmware booted");
release_firmware(priv->fw);
init_avl62x1_i2cctl_device(priv);
#if INCLUDE_STDOUT
init_avl62x1_stdout_device(priv);
#endif

return &priv->frontend;
}
Expand Down
2 changes: 1 addition & 1 deletion availink/avl62x1/sdk_src/avl62x1_lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
//build number = increment on every change to implementation
#define AVL62X1_VER_MAJOR 3
#define AVL62X1_VER_MINOR 8
#define AVL62X1_VER_BUILD 3
#define AVL62X1_VER_BUILD 4

#define AVL62X1_CHIP_ID 0x62615ca8

Expand Down
Loading

0 comments on commit 1f94fb6

Please sign in to comment.