Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Abilis Systems Single DVB-T Receiver
0004  * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
0005  */
0006 
0007 #include <linux/kernel.h>
0008 #include "as102_drv.h"
0009 #include "as10x_cmd.h"
0010 
0011 /***************************/
0012 /* FUNCTION DEFINITION     */
0013 /***************************/
0014 
0015 /**
0016  * as10x_cmd_get_context - Send get context command to AS10x
0017  * @adap:      pointer to AS10x bus adapter
0018  * @tag:       context tag
0019  * @pvalue:    pointer where to store context value read
0020  *
0021  * Return 0 on success or negative value in case of error.
0022  */
0023 int as10x_cmd_get_context(struct as10x_bus_adapter_t *adap, uint16_t tag,
0024               uint32_t *pvalue)
0025 {
0026     int  error;
0027     struct as10x_cmd_t *pcmd, *prsp;
0028 
0029     pcmd = adap->cmd;
0030     prsp = adap->rsp;
0031 
0032     /* prepare command */
0033     as10x_cmd_build(pcmd, (++adap->cmd_xid),
0034             sizeof(pcmd->body.context.req));
0035 
0036     /* fill command */
0037     pcmd->body.context.req.proc_id = cpu_to_le16(CONTROL_PROC_CONTEXT);
0038     pcmd->body.context.req.tag = cpu_to_le16(tag);
0039     pcmd->body.context.req.type = cpu_to_le16(GET_CONTEXT_DATA);
0040 
0041     /* send command */
0042     if (adap->ops->xfer_cmd) {
0043         error  = adap->ops->xfer_cmd(adap,
0044                          (uint8_t *) pcmd,
0045                          sizeof(pcmd->body.context.req)
0046                          + HEADER_SIZE,
0047                          (uint8_t *) prsp,
0048                          sizeof(prsp->body.context.rsp)
0049                          + HEADER_SIZE);
0050     } else {
0051         error = AS10X_CMD_ERROR;
0052     }
0053 
0054     if (error < 0)
0055         goto out;
0056 
0057     /* parse response: context command do not follow the common response */
0058     /* structure -> specific handling response parse required            */
0059     error = as10x_context_rsp_parse(prsp, CONTROL_PROC_CONTEXT_RSP);
0060 
0061     if (error == 0) {
0062         /* Response OK -> get response data */
0063         *pvalue = le32_to_cpu((__force __le32)prsp->body.context.rsp.reg_val.u.value32);
0064         /* value returned is always a 32-bit value */
0065     }
0066 
0067 out:
0068     return error;
0069 }
0070 
0071 /**
0072  * as10x_cmd_set_context - send set context command to AS10x
0073  * @adap:      pointer to AS10x bus adapter
0074  * @tag:       context tag
0075  * @value:     value to set in context
0076  *
0077  * Return 0 on success or negative value in case of error.
0078  */
0079 int as10x_cmd_set_context(struct as10x_bus_adapter_t *adap, uint16_t tag,
0080               uint32_t value)
0081 {
0082     int error;
0083     struct as10x_cmd_t *pcmd, *prsp;
0084 
0085     pcmd = adap->cmd;
0086     prsp = adap->rsp;
0087 
0088     /* prepare command */
0089     as10x_cmd_build(pcmd, (++adap->cmd_xid),
0090             sizeof(pcmd->body.context.req));
0091 
0092     /* fill command */
0093     pcmd->body.context.req.proc_id = cpu_to_le16(CONTROL_PROC_CONTEXT);
0094     /* pcmd->body.context.req.reg_val.mode initialization is not required */
0095     pcmd->body.context.req.reg_val.u.value32 = (__force u32)cpu_to_le32(value);
0096     pcmd->body.context.req.tag = cpu_to_le16(tag);
0097     pcmd->body.context.req.type = cpu_to_le16(SET_CONTEXT_DATA);
0098 
0099     /* send command */
0100     if (adap->ops->xfer_cmd) {
0101         error  = adap->ops->xfer_cmd(adap,
0102                          (uint8_t *) pcmd,
0103                          sizeof(pcmd->body.context.req)
0104                          + HEADER_SIZE,
0105                          (uint8_t *) prsp,
0106                          sizeof(prsp->body.context.rsp)
0107                          + HEADER_SIZE);
0108     } else {
0109         error = AS10X_CMD_ERROR;
0110     }
0111 
0112     if (error < 0)
0113         goto out;
0114 
0115     /* parse response: context command do not follow the common response */
0116     /* structure -> specific handling response parse required            */
0117     error = as10x_context_rsp_parse(prsp, CONTROL_PROC_CONTEXT_RSP);
0118 
0119 out:
0120     return error;
0121 }
0122 
0123 /**
0124  * as10x_cmd_eLNA_change_mode - send eLNA change mode command to AS10x
0125  * @adap:      pointer to AS10x bus adapter
0126  * @mode:      mode selected:
0127  *      - ON    : 0x0 => eLNA always ON
0128  *      - OFF   : 0x1 => eLNA always OFF
0129  *      - AUTO  : 0x2 => eLNA follow hysteresis parameters
0130  *               to be ON or OFF
0131  *
0132  * Return 0 on success or negative value in case of error.
0133  */
0134 int as10x_cmd_eLNA_change_mode(struct as10x_bus_adapter_t *adap, uint8_t mode)
0135 {
0136     int error;
0137     struct as10x_cmd_t *pcmd, *prsp;
0138 
0139     pcmd = adap->cmd;
0140     prsp = adap->rsp;
0141 
0142     /* prepare command */
0143     as10x_cmd_build(pcmd, (++adap->cmd_xid),
0144             sizeof(pcmd->body.cfg_change_mode.req));
0145 
0146     /* fill command */
0147     pcmd->body.cfg_change_mode.req.proc_id =
0148         cpu_to_le16(CONTROL_PROC_ELNA_CHANGE_MODE);
0149     pcmd->body.cfg_change_mode.req.mode = mode;
0150 
0151     /* send command */
0152     if (adap->ops->xfer_cmd) {
0153         error  = adap->ops->xfer_cmd(adap, (uint8_t *) pcmd,
0154                 sizeof(pcmd->body.cfg_change_mode.req)
0155                 + HEADER_SIZE, (uint8_t *) prsp,
0156                 sizeof(prsp->body.cfg_change_mode.rsp)
0157                 + HEADER_SIZE);
0158     } else {
0159         error = AS10X_CMD_ERROR;
0160     }
0161 
0162     if (error < 0)
0163         goto out;
0164 
0165     /* parse response */
0166     error = as10x_rsp_parse(prsp, CONTROL_PROC_ELNA_CHANGE_MODE_RSP);
0167 
0168 out:
0169     return error;
0170 }
0171 
0172 /**
0173  * as10x_context_rsp_parse - Parse context command response
0174  * @prsp:       pointer to AS10x command response buffer
0175  * @proc_id:    id of the command
0176  *
0177  * Since the contex command response does not follow the common
0178  * response, a specific parse function is required.
0179  * Return 0 on success or negative value in case of error.
0180  */
0181 int as10x_context_rsp_parse(struct as10x_cmd_t *prsp, uint16_t proc_id)
0182 {
0183     int err;
0184 
0185     err = prsp->body.context.rsp.error;
0186 
0187     if ((err == 0) &&
0188         (le16_to_cpu(prsp->body.context.rsp.proc_id) == proc_id)) {
0189         return 0;
0190     }
0191     return AS10X_CMD_ERROR;
0192 }