misc: xilinx_sdfec: Add ability to get/set config
- Add capability to get SD-FEC config data using ioctl XSDFEC_GET_CONFIG. - Add capability to set SD-FEC data order using ioctl SDFEC_SET_ORDER. - Add capability to set SD-FEC bypass option using ioctl XSDFEC_SET_BYPASS. - Add capability to set SD-FEC active state using ioctl XSDFEC_IS_ACTIVE. Tested-by: Dragan Cvetic <dragan.cvetic@xilinx.com> Signed-off-by: Derek Kiernan <derek.kiernan@xilinx.com> Signed-off-by: Dragan Cvetic <dragan.cvetic@xilinx.com> Link: https://lore.kernel.org/r/1564216438-322406-5-git-send-email-dragan.cvetic@xilinx.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Родитель
20ec628e80
Коммит
77dd39d924
|
@ -273,6 +273,17 @@ static void update_config_from_hw(struct xsdfec_dev *xsdfec)
|
||||||
xsdfec->state = XSDFEC_STOPPED;
|
xsdfec->state = XSDFEC_STOPPED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int xsdfec_get_config(struct xsdfec_dev *xsdfec, void __user *arg)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = copy_to_user(arg, &xsdfec->config, sizeof(xsdfec->config));
|
||||||
|
if (err)
|
||||||
|
err = -EFAULT;
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
static int xsdfec_set_turbo(struct xsdfec_dev *xsdfec, void __user *arg)
|
static int xsdfec_set_turbo(struct xsdfec_dev *xsdfec, void __user *arg)
|
||||||
{
|
{
|
||||||
struct xsdfec_turbo turbo;
|
struct xsdfec_turbo turbo;
|
||||||
|
@ -591,6 +602,71 @@ err_out:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int xsdfec_set_order(struct xsdfec_dev *xsdfec, void __user *arg)
|
||||||
|
{
|
||||||
|
bool order_invalid;
|
||||||
|
enum xsdfec_order order;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = get_user(order, (enum xsdfec_order *)arg);
|
||||||
|
if (err)
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
order_invalid = (order != XSDFEC_MAINTAIN_ORDER) &&
|
||||||
|
(order != XSDFEC_OUT_OF_ORDER);
|
||||||
|
if (order_invalid)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
/* Verify Device has not started */
|
||||||
|
if (xsdfec->state == XSDFEC_STARTED)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
xsdfec_regwrite(xsdfec, XSDFEC_ORDER_ADDR, order);
|
||||||
|
|
||||||
|
xsdfec->config.order = order;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int xsdfec_set_bypass(struct xsdfec_dev *xsdfec, bool __user *arg)
|
||||||
|
{
|
||||||
|
bool bypass;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = get_user(bypass, arg);
|
||||||
|
if (err)
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
/* Verify Device has not started */
|
||||||
|
if (xsdfec->state == XSDFEC_STARTED)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
if (bypass)
|
||||||
|
xsdfec_regwrite(xsdfec, XSDFEC_BYPASS_ADDR, 1);
|
||||||
|
else
|
||||||
|
xsdfec_regwrite(xsdfec, XSDFEC_BYPASS_ADDR, 0);
|
||||||
|
|
||||||
|
xsdfec->config.bypass = bypass;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int xsdfec_is_active(struct xsdfec_dev *xsdfec, bool __user *arg)
|
||||||
|
{
|
||||||
|
u32 reg_value;
|
||||||
|
bool is_active;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
reg_value = xsdfec_regread(xsdfec, XSDFEC_ACTIVE_ADDR);
|
||||||
|
/* using a double ! operator instead of casting */
|
||||||
|
is_active = !!(reg_value & XSDFEC_IS_ACTIVITY_SET);
|
||||||
|
err = put_user(is_active, arg);
|
||||||
|
if (err)
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
static u32
|
static u32
|
||||||
xsdfec_translate_axis_width_cfg_val(enum xsdfec_axis_width axis_width_cfg)
|
xsdfec_translate_axis_width_cfg_val(enum xsdfec_axis_width axis_width_cfg)
|
||||||
{
|
{
|
||||||
|
@ -681,6 +757,9 @@ static long xsdfec_dev_ioctl(struct file *fptr, unsigned int cmd,
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
|
case XSDFEC_GET_CONFIG:
|
||||||
|
rval = xsdfec_get_config(xsdfec, arg);
|
||||||
|
break;
|
||||||
case XSDFEC_SET_TURBO:
|
case XSDFEC_SET_TURBO:
|
||||||
rval = xsdfec_set_turbo(xsdfec, arg);
|
rval = xsdfec_set_turbo(xsdfec, arg);
|
||||||
break;
|
break;
|
||||||
|
@ -690,6 +769,15 @@ static long xsdfec_dev_ioctl(struct file *fptr, unsigned int cmd,
|
||||||
case XSDFEC_ADD_LDPC_CODE_PARAMS:
|
case XSDFEC_ADD_LDPC_CODE_PARAMS:
|
||||||
rval = xsdfec_add_ldpc(xsdfec, arg);
|
rval = xsdfec_add_ldpc(xsdfec, arg);
|
||||||
break;
|
break;
|
||||||
|
case XSDFEC_SET_ORDER:
|
||||||
|
rval = xsdfec_set_order(xsdfec, arg);
|
||||||
|
break;
|
||||||
|
case XSDFEC_SET_BYPASS:
|
||||||
|
rval = xsdfec_set_bypass(xsdfec, arg);
|
||||||
|
break;
|
||||||
|
case XSDFEC_IS_ACTIVE:
|
||||||
|
rval = xsdfec_is_active(xsdfec, (bool __user *)arg);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
/* Should not get here */
|
/* Should not get here */
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -287,6 +287,19 @@ struct xsdfec_ldpc_param_table_sizes {
|
||||||
*/
|
*/
|
||||||
#define XSDFEC_ADD_LDPC_CODE_PARAMS \
|
#define XSDFEC_ADD_LDPC_CODE_PARAMS \
|
||||||
_IOW(XSDFEC_MAGIC, 5, struct xsdfec_ldpc_params)
|
_IOW(XSDFEC_MAGIC, 5, struct xsdfec_ldpc_params)
|
||||||
|
/**
|
||||||
|
* DOC: XSDFEC_GET_CONFIG
|
||||||
|
* @Parameters
|
||||||
|
*
|
||||||
|
* @struct xsdfec_config *
|
||||||
|
* Pointer to the &struct xsdfec_config that contains the current
|
||||||
|
* configuration settings of the SD-FEC Block
|
||||||
|
*
|
||||||
|
* @Description
|
||||||
|
*
|
||||||
|
* ioctl that returns SD-FEC core configuration
|
||||||
|
*/
|
||||||
|
#define XSDFEC_GET_CONFIG _IOR(XSDFEC_MAGIC, 6, struct xsdfec_config)
|
||||||
/**
|
/**
|
||||||
* DOC: XSDFEC_GET_TURBO
|
* DOC: XSDFEC_GET_TURBO
|
||||||
* @Parameters
|
* @Parameters
|
||||||
|
@ -300,4 +313,48 @@ struct xsdfec_ldpc_param_table_sizes {
|
||||||
* ioctl that returns SD-FEC turbo param values
|
* ioctl that returns SD-FEC turbo param values
|
||||||
*/
|
*/
|
||||||
#define XSDFEC_GET_TURBO _IOR(XSDFEC_MAGIC, 7, struct xsdfec_turbo)
|
#define XSDFEC_GET_TURBO _IOR(XSDFEC_MAGIC, 7, struct xsdfec_turbo)
|
||||||
|
/**
|
||||||
|
* DOC: XSDFEC_SET_ORDER
|
||||||
|
* @Parameters
|
||||||
|
*
|
||||||
|
* @struct unsigned long *
|
||||||
|
* Pointer to the unsigned long that contains a value from the
|
||||||
|
* @enum xsdfec_order
|
||||||
|
*
|
||||||
|
* @Description
|
||||||
|
*
|
||||||
|
* ioctl that sets order, if order of blocks can change from input to output
|
||||||
|
*
|
||||||
|
* This can only be used when the driver is in the XSDFEC_STOPPED state
|
||||||
|
*/
|
||||||
|
#define XSDFEC_SET_ORDER _IOW(XSDFEC_MAGIC, 8, unsigned long)
|
||||||
|
/**
|
||||||
|
* DOC: XSDFEC_SET_BYPASS
|
||||||
|
* @Parameters
|
||||||
|
*
|
||||||
|
* @struct bool *
|
||||||
|
* Pointer to bool that sets the bypass value, where false results in
|
||||||
|
* normal operation and false results in the SD-FEC performing the
|
||||||
|
* configured operations (same number of cycles) but output data matches
|
||||||
|
* the input data
|
||||||
|
*
|
||||||
|
* @Description
|
||||||
|
*
|
||||||
|
* ioctl that sets bypass.
|
||||||
|
*
|
||||||
|
* This can only be used when the driver is in the XSDFEC_STOPPED state
|
||||||
|
*/
|
||||||
|
#define XSDFEC_SET_BYPASS _IOW(XSDFEC_MAGIC, 9, bool)
|
||||||
|
/**
|
||||||
|
* DOC: XSDFEC_IS_ACTIVE
|
||||||
|
* @Parameters
|
||||||
|
*
|
||||||
|
* @struct bool *
|
||||||
|
* Pointer to bool that returns true if the SD-FEC is processing data
|
||||||
|
*
|
||||||
|
* @Description
|
||||||
|
*
|
||||||
|
* ioctl that determines if SD-FEC is processing data
|
||||||
|
*/
|
||||||
|
#define XSDFEC_IS_ACTIVE _IOR(XSDFEC_MAGIC, 10, bool)
|
||||||
#endif /* __XILINX_SDFEC_H__ */
|
#endif /* __XILINX_SDFEC_H__ */
|
||||||
|
|
Загрузка…
Ссылка в новой задаче