18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Abilis Systems Single DVB-T Receiver 48c2ecf20Sopenharmony_ci * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com> 58c2ecf20Sopenharmony_ci * Copyright (C) 2010 Devin Heitmueller <dheitmueller@kernellabs.com> 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include <linux/kernel.h> 98c2ecf20Sopenharmony_ci#include "as102_drv.h" 108c2ecf20Sopenharmony_ci#include "as10x_cmd.h" 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci/** 138c2ecf20Sopenharmony_ci * as10x_cmd_turn_on - send turn on command to AS10x 148c2ecf20Sopenharmony_ci * @adap: pointer to AS10x bus adapter 158c2ecf20Sopenharmony_ci * 168c2ecf20Sopenharmony_ci * Return 0 when no error, < 0 in case of error. 178c2ecf20Sopenharmony_ci */ 188c2ecf20Sopenharmony_ciint as10x_cmd_turn_on(struct as10x_bus_adapter_t *adap) 198c2ecf20Sopenharmony_ci{ 208c2ecf20Sopenharmony_ci int error = AS10X_CMD_ERROR; 218c2ecf20Sopenharmony_ci struct as10x_cmd_t *pcmd, *prsp; 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci pcmd = adap->cmd; 248c2ecf20Sopenharmony_ci prsp = adap->rsp; 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci /* prepare command */ 278c2ecf20Sopenharmony_ci as10x_cmd_build(pcmd, (++adap->cmd_xid), 288c2ecf20Sopenharmony_ci sizeof(pcmd->body.turn_on.req)); 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci /* fill command */ 318c2ecf20Sopenharmony_ci pcmd->body.turn_on.req.proc_id = cpu_to_le16(CONTROL_PROC_TURNON); 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci /* send command */ 348c2ecf20Sopenharmony_ci if (adap->ops->xfer_cmd) { 358c2ecf20Sopenharmony_ci error = adap->ops->xfer_cmd(adap, (uint8_t *) pcmd, 368c2ecf20Sopenharmony_ci sizeof(pcmd->body.turn_on.req) + 378c2ecf20Sopenharmony_ci HEADER_SIZE, 388c2ecf20Sopenharmony_ci (uint8_t *) prsp, 398c2ecf20Sopenharmony_ci sizeof(prsp->body.turn_on.rsp) + 408c2ecf20Sopenharmony_ci HEADER_SIZE); 418c2ecf20Sopenharmony_ci } 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci if (error < 0) 448c2ecf20Sopenharmony_ci goto out; 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci /* parse response */ 478c2ecf20Sopenharmony_ci error = as10x_rsp_parse(prsp, CONTROL_PROC_TURNON_RSP); 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ciout: 508c2ecf20Sopenharmony_ci return error; 518c2ecf20Sopenharmony_ci} 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci/** 548c2ecf20Sopenharmony_ci * as10x_cmd_turn_off - send turn off command to AS10x 558c2ecf20Sopenharmony_ci * @adap: pointer to AS10x bus adapter 568c2ecf20Sopenharmony_ci * 578c2ecf20Sopenharmony_ci * Return 0 on success or negative value in case of error. 588c2ecf20Sopenharmony_ci */ 598c2ecf20Sopenharmony_ciint as10x_cmd_turn_off(struct as10x_bus_adapter_t *adap) 608c2ecf20Sopenharmony_ci{ 618c2ecf20Sopenharmony_ci int error = AS10X_CMD_ERROR; 628c2ecf20Sopenharmony_ci struct as10x_cmd_t *pcmd, *prsp; 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci pcmd = adap->cmd; 658c2ecf20Sopenharmony_ci prsp = adap->rsp; 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci /* prepare command */ 688c2ecf20Sopenharmony_ci as10x_cmd_build(pcmd, (++adap->cmd_xid), 698c2ecf20Sopenharmony_ci sizeof(pcmd->body.turn_off.req)); 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci /* fill command */ 728c2ecf20Sopenharmony_ci pcmd->body.turn_off.req.proc_id = cpu_to_le16(CONTROL_PROC_TURNOFF); 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci /* send command */ 758c2ecf20Sopenharmony_ci if (adap->ops->xfer_cmd) { 768c2ecf20Sopenharmony_ci error = adap->ops->xfer_cmd( 778c2ecf20Sopenharmony_ci adap, (uint8_t *) pcmd, 788c2ecf20Sopenharmony_ci sizeof(pcmd->body.turn_off.req) + HEADER_SIZE, 798c2ecf20Sopenharmony_ci (uint8_t *) prsp, 808c2ecf20Sopenharmony_ci sizeof(prsp->body.turn_off.rsp) + HEADER_SIZE); 818c2ecf20Sopenharmony_ci } 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci if (error < 0) 848c2ecf20Sopenharmony_ci goto out; 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci /* parse response */ 878c2ecf20Sopenharmony_ci error = as10x_rsp_parse(prsp, CONTROL_PROC_TURNOFF_RSP); 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ciout: 908c2ecf20Sopenharmony_ci return error; 918c2ecf20Sopenharmony_ci} 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ci/** 948c2ecf20Sopenharmony_ci * as10x_cmd_set_tune - send set tune command to AS10x 958c2ecf20Sopenharmony_ci * @adap: pointer to AS10x bus adapter 968c2ecf20Sopenharmony_ci * @ptune: tune parameters 978c2ecf20Sopenharmony_ci * 988c2ecf20Sopenharmony_ci * Return 0 on success or negative value in case of error. 998c2ecf20Sopenharmony_ci */ 1008c2ecf20Sopenharmony_ciint as10x_cmd_set_tune(struct as10x_bus_adapter_t *adap, 1018c2ecf20Sopenharmony_ci struct as10x_tune_args *ptune) 1028c2ecf20Sopenharmony_ci{ 1038c2ecf20Sopenharmony_ci int error = AS10X_CMD_ERROR; 1048c2ecf20Sopenharmony_ci struct as10x_cmd_t *preq, *prsp; 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_ci preq = adap->cmd; 1078c2ecf20Sopenharmony_ci prsp = adap->rsp; 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ci /* prepare command */ 1108c2ecf20Sopenharmony_ci as10x_cmd_build(preq, (++adap->cmd_xid), 1118c2ecf20Sopenharmony_ci sizeof(preq->body.set_tune.req)); 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_ci /* fill command */ 1148c2ecf20Sopenharmony_ci preq->body.set_tune.req.proc_id = cpu_to_le16(CONTROL_PROC_SETTUNE); 1158c2ecf20Sopenharmony_ci preq->body.set_tune.req.args.freq = (__force __u32)cpu_to_le32(ptune->freq); 1168c2ecf20Sopenharmony_ci preq->body.set_tune.req.args.bandwidth = ptune->bandwidth; 1178c2ecf20Sopenharmony_ci preq->body.set_tune.req.args.hier_select = ptune->hier_select; 1188c2ecf20Sopenharmony_ci preq->body.set_tune.req.args.modulation = ptune->modulation; 1198c2ecf20Sopenharmony_ci preq->body.set_tune.req.args.hierarchy = ptune->hierarchy; 1208c2ecf20Sopenharmony_ci preq->body.set_tune.req.args.interleaving_mode = 1218c2ecf20Sopenharmony_ci ptune->interleaving_mode; 1228c2ecf20Sopenharmony_ci preq->body.set_tune.req.args.code_rate = ptune->code_rate; 1238c2ecf20Sopenharmony_ci preq->body.set_tune.req.args.guard_interval = ptune->guard_interval; 1248c2ecf20Sopenharmony_ci preq->body.set_tune.req.args.transmission_mode = 1258c2ecf20Sopenharmony_ci ptune->transmission_mode; 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_ci /* send command */ 1288c2ecf20Sopenharmony_ci if (adap->ops->xfer_cmd) { 1298c2ecf20Sopenharmony_ci error = adap->ops->xfer_cmd(adap, 1308c2ecf20Sopenharmony_ci (uint8_t *) preq, 1318c2ecf20Sopenharmony_ci sizeof(preq->body.set_tune.req) 1328c2ecf20Sopenharmony_ci + HEADER_SIZE, 1338c2ecf20Sopenharmony_ci (uint8_t *) prsp, 1348c2ecf20Sopenharmony_ci sizeof(prsp->body.set_tune.rsp) 1358c2ecf20Sopenharmony_ci + HEADER_SIZE); 1368c2ecf20Sopenharmony_ci } 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_ci if (error < 0) 1398c2ecf20Sopenharmony_ci goto out; 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_ci /* parse response */ 1428c2ecf20Sopenharmony_ci error = as10x_rsp_parse(prsp, CONTROL_PROC_SETTUNE_RSP); 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_ciout: 1458c2ecf20Sopenharmony_ci return error; 1468c2ecf20Sopenharmony_ci} 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci/** 1498c2ecf20Sopenharmony_ci * as10x_cmd_get_tune_status - send get tune status command to AS10x 1508c2ecf20Sopenharmony_ci * @adap: pointer to AS10x bus adapter 1518c2ecf20Sopenharmony_ci * @pstatus: pointer to updated status structure of the current tune 1528c2ecf20Sopenharmony_ci * 1538c2ecf20Sopenharmony_ci * Return 0 on success or negative value in case of error. 1548c2ecf20Sopenharmony_ci */ 1558c2ecf20Sopenharmony_ciint as10x_cmd_get_tune_status(struct as10x_bus_adapter_t *adap, 1568c2ecf20Sopenharmony_ci struct as10x_tune_status *pstatus) 1578c2ecf20Sopenharmony_ci{ 1588c2ecf20Sopenharmony_ci int error = AS10X_CMD_ERROR; 1598c2ecf20Sopenharmony_ci struct as10x_cmd_t *preq, *prsp; 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_ci preq = adap->cmd; 1628c2ecf20Sopenharmony_ci prsp = adap->rsp; 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_ci /* prepare command */ 1658c2ecf20Sopenharmony_ci as10x_cmd_build(preq, (++adap->cmd_xid), 1668c2ecf20Sopenharmony_ci sizeof(preq->body.get_tune_status.req)); 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_ci /* fill command */ 1698c2ecf20Sopenharmony_ci preq->body.get_tune_status.req.proc_id = 1708c2ecf20Sopenharmony_ci cpu_to_le16(CONTROL_PROC_GETTUNESTAT); 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_ci /* send command */ 1738c2ecf20Sopenharmony_ci if (adap->ops->xfer_cmd) { 1748c2ecf20Sopenharmony_ci error = adap->ops->xfer_cmd( 1758c2ecf20Sopenharmony_ci adap, 1768c2ecf20Sopenharmony_ci (uint8_t *) preq, 1778c2ecf20Sopenharmony_ci sizeof(preq->body.get_tune_status.req) + HEADER_SIZE, 1788c2ecf20Sopenharmony_ci (uint8_t *) prsp, 1798c2ecf20Sopenharmony_ci sizeof(prsp->body.get_tune_status.rsp) + HEADER_SIZE); 1808c2ecf20Sopenharmony_ci } 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_ci if (error < 0) 1838c2ecf20Sopenharmony_ci goto out; 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_ci /* parse response */ 1868c2ecf20Sopenharmony_ci error = as10x_rsp_parse(prsp, CONTROL_PROC_GETTUNESTAT_RSP); 1878c2ecf20Sopenharmony_ci if (error < 0) 1888c2ecf20Sopenharmony_ci goto out; 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_ci /* Response OK -> get response data */ 1918c2ecf20Sopenharmony_ci pstatus->tune_state = prsp->body.get_tune_status.rsp.sts.tune_state; 1928c2ecf20Sopenharmony_ci pstatus->signal_strength = 1938c2ecf20Sopenharmony_ci le16_to_cpu((__force __le16)prsp->body.get_tune_status.rsp.sts.signal_strength); 1948c2ecf20Sopenharmony_ci pstatus->PER = le16_to_cpu((__force __le16)prsp->body.get_tune_status.rsp.sts.PER); 1958c2ecf20Sopenharmony_ci pstatus->BER = le16_to_cpu((__force __le16)prsp->body.get_tune_status.rsp.sts.BER); 1968c2ecf20Sopenharmony_ci 1978c2ecf20Sopenharmony_ciout: 1988c2ecf20Sopenharmony_ci return error; 1998c2ecf20Sopenharmony_ci} 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_ci/** 2028c2ecf20Sopenharmony_ci * as10x_cmd_get_tps - send get TPS command to AS10x 2038c2ecf20Sopenharmony_ci * @adap: pointer to AS10x handle 2048c2ecf20Sopenharmony_ci * @ptps: pointer to TPS parameters structure 2058c2ecf20Sopenharmony_ci * 2068c2ecf20Sopenharmony_ci * Return 0 on success or negative value in case of error. 2078c2ecf20Sopenharmony_ci */ 2088c2ecf20Sopenharmony_ciint as10x_cmd_get_tps(struct as10x_bus_adapter_t *adap, struct as10x_tps *ptps) 2098c2ecf20Sopenharmony_ci{ 2108c2ecf20Sopenharmony_ci int error = AS10X_CMD_ERROR; 2118c2ecf20Sopenharmony_ci struct as10x_cmd_t *pcmd, *prsp; 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_ci pcmd = adap->cmd; 2148c2ecf20Sopenharmony_ci prsp = adap->rsp; 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ci /* prepare command */ 2178c2ecf20Sopenharmony_ci as10x_cmd_build(pcmd, (++adap->cmd_xid), 2188c2ecf20Sopenharmony_ci sizeof(pcmd->body.get_tps.req)); 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_ci /* fill command */ 2218c2ecf20Sopenharmony_ci pcmd->body.get_tune_status.req.proc_id = 2228c2ecf20Sopenharmony_ci cpu_to_le16(CONTROL_PROC_GETTPS); 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_ci /* send command */ 2258c2ecf20Sopenharmony_ci if (adap->ops->xfer_cmd) { 2268c2ecf20Sopenharmony_ci error = adap->ops->xfer_cmd(adap, 2278c2ecf20Sopenharmony_ci (uint8_t *) pcmd, 2288c2ecf20Sopenharmony_ci sizeof(pcmd->body.get_tps.req) + 2298c2ecf20Sopenharmony_ci HEADER_SIZE, 2308c2ecf20Sopenharmony_ci (uint8_t *) prsp, 2318c2ecf20Sopenharmony_ci sizeof(prsp->body.get_tps.rsp) + 2328c2ecf20Sopenharmony_ci HEADER_SIZE); 2338c2ecf20Sopenharmony_ci } 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_ci if (error < 0) 2368c2ecf20Sopenharmony_ci goto out; 2378c2ecf20Sopenharmony_ci 2388c2ecf20Sopenharmony_ci /* parse response */ 2398c2ecf20Sopenharmony_ci error = as10x_rsp_parse(prsp, CONTROL_PROC_GETTPS_RSP); 2408c2ecf20Sopenharmony_ci if (error < 0) 2418c2ecf20Sopenharmony_ci goto out; 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_ci /* Response OK -> get response data */ 2448c2ecf20Sopenharmony_ci ptps->modulation = prsp->body.get_tps.rsp.tps.modulation; 2458c2ecf20Sopenharmony_ci ptps->hierarchy = prsp->body.get_tps.rsp.tps.hierarchy; 2468c2ecf20Sopenharmony_ci ptps->interleaving_mode = prsp->body.get_tps.rsp.tps.interleaving_mode; 2478c2ecf20Sopenharmony_ci ptps->code_rate_HP = prsp->body.get_tps.rsp.tps.code_rate_HP; 2488c2ecf20Sopenharmony_ci ptps->code_rate_LP = prsp->body.get_tps.rsp.tps.code_rate_LP; 2498c2ecf20Sopenharmony_ci ptps->guard_interval = prsp->body.get_tps.rsp.tps.guard_interval; 2508c2ecf20Sopenharmony_ci ptps->transmission_mode = prsp->body.get_tps.rsp.tps.transmission_mode; 2518c2ecf20Sopenharmony_ci ptps->DVBH_mask_HP = prsp->body.get_tps.rsp.tps.DVBH_mask_HP; 2528c2ecf20Sopenharmony_ci ptps->DVBH_mask_LP = prsp->body.get_tps.rsp.tps.DVBH_mask_LP; 2538c2ecf20Sopenharmony_ci ptps->cell_ID = le16_to_cpu((__force __le16)prsp->body.get_tps.rsp.tps.cell_ID); 2548c2ecf20Sopenharmony_ci 2558c2ecf20Sopenharmony_ciout: 2568c2ecf20Sopenharmony_ci return error; 2578c2ecf20Sopenharmony_ci} 2588c2ecf20Sopenharmony_ci 2598c2ecf20Sopenharmony_ci/** 2608c2ecf20Sopenharmony_ci * as10x_cmd_get_demod_stats - send get demod stats command to AS10x 2618c2ecf20Sopenharmony_ci * @adap: pointer to AS10x bus adapter 2628c2ecf20Sopenharmony_ci * @pdemod_stats: pointer to demod stats parameters structure 2638c2ecf20Sopenharmony_ci * 2648c2ecf20Sopenharmony_ci * Return 0 on success or negative value in case of error. 2658c2ecf20Sopenharmony_ci */ 2668c2ecf20Sopenharmony_ciint as10x_cmd_get_demod_stats(struct as10x_bus_adapter_t *adap, 2678c2ecf20Sopenharmony_ci struct as10x_demod_stats *pdemod_stats) 2688c2ecf20Sopenharmony_ci{ 2698c2ecf20Sopenharmony_ci int error = AS10X_CMD_ERROR; 2708c2ecf20Sopenharmony_ci struct as10x_cmd_t *pcmd, *prsp; 2718c2ecf20Sopenharmony_ci 2728c2ecf20Sopenharmony_ci pcmd = adap->cmd; 2738c2ecf20Sopenharmony_ci prsp = adap->rsp; 2748c2ecf20Sopenharmony_ci 2758c2ecf20Sopenharmony_ci /* prepare command */ 2768c2ecf20Sopenharmony_ci as10x_cmd_build(pcmd, (++adap->cmd_xid), 2778c2ecf20Sopenharmony_ci sizeof(pcmd->body.get_demod_stats.req)); 2788c2ecf20Sopenharmony_ci 2798c2ecf20Sopenharmony_ci /* fill command */ 2808c2ecf20Sopenharmony_ci pcmd->body.get_demod_stats.req.proc_id = 2818c2ecf20Sopenharmony_ci cpu_to_le16(CONTROL_PROC_GET_DEMOD_STATS); 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_ci /* send command */ 2848c2ecf20Sopenharmony_ci if (adap->ops->xfer_cmd) { 2858c2ecf20Sopenharmony_ci error = adap->ops->xfer_cmd(adap, 2868c2ecf20Sopenharmony_ci (uint8_t *) pcmd, 2878c2ecf20Sopenharmony_ci sizeof(pcmd->body.get_demod_stats.req) 2888c2ecf20Sopenharmony_ci + HEADER_SIZE, 2898c2ecf20Sopenharmony_ci (uint8_t *) prsp, 2908c2ecf20Sopenharmony_ci sizeof(prsp->body.get_demod_stats.rsp) 2918c2ecf20Sopenharmony_ci + HEADER_SIZE); 2928c2ecf20Sopenharmony_ci } 2938c2ecf20Sopenharmony_ci 2948c2ecf20Sopenharmony_ci if (error < 0) 2958c2ecf20Sopenharmony_ci goto out; 2968c2ecf20Sopenharmony_ci 2978c2ecf20Sopenharmony_ci /* parse response */ 2988c2ecf20Sopenharmony_ci error = as10x_rsp_parse(prsp, CONTROL_PROC_GET_DEMOD_STATS_RSP); 2998c2ecf20Sopenharmony_ci if (error < 0) 3008c2ecf20Sopenharmony_ci goto out; 3018c2ecf20Sopenharmony_ci 3028c2ecf20Sopenharmony_ci /* Response OK -> get response data */ 3038c2ecf20Sopenharmony_ci pdemod_stats->frame_count = 3048c2ecf20Sopenharmony_ci le32_to_cpu((__force __le32)prsp->body.get_demod_stats.rsp.stats.frame_count); 3058c2ecf20Sopenharmony_ci pdemod_stats->bad_frame_count = 3068c2ecf20Sopenharmony_ci le32_to_cpu((__force __le32)prsp->body.get_demod_stats.rsp.stats.bad_frame_count); 3078c2ecf20Sopenharmony_ci pdemod_stats->bytes_fixed_by_rs = 3088c2ecf20Sopenharmony_ci le32_to_cpu((__force __le32)prsp->body.get_demod_stats.rsp.stats.bytes_fixed_by_rs); 3098c2ecf20Sopenharmony_ci pdemod_stats->mer = 3108c2ecf20Sopenharmony_ci le16_to_cpu((__force __le16)prsp->body.get_demod_stats.rsp.stats.mer); 3118c2ecf20Sopenharmony_ci pdemod_stats->has_started = 3128c2ecf20Sopenharmony_ci prsp->body.get_demod_stats.rsp.stats.has_started; 3138c2ecf20Sopenharmony_ci 3148c2ecf20Sopenharmony_ciout: 3158c2ecf20Sopenharmony_ci return error; 3168c2ecf20Sopenharmony_ci} 3178c2ecf20Sopenharmony_ci 3188c2ecf20Sopenharmony_ci/** 3198c2ecf20Sopenharmony_ci * as10x_cmd_get_impulse_resp - send get impulse response command to AS10x 3208c2ecf20Sopenharmony_ci * @adap: pointer to AS10x bus adapter 3218c2ecf20Sopenharmony_ci * @is_ready: pointer to value indicating when impulse 3228c2ecf20Sopenharmony_ci * response data is ready 3238c2ecf20Sopenharmony_ci * 3248c2ecf20Sopenharmony_ci * Return 0 on success or negative value in case of error. 3258c2ecf20Sopenharmony_ci */ 3268c2ecf20Sopenharmony_ciint as10x_cmd_get_impulse_resp(struct as10x_bus_adapter_t *adap, 3278c2ecf20Sopenharmony_ci uint8_t *is_ready) 3288c2ecf20Sopenharmony_ci{ 3298c2ecf20Sopenharmony_ci int error = AS10X_CMD_ERROR; 3308c2ecf20Sopenharmony_ci struct as10x_cmd_t *pcmd, *prsp; 3318c2ecf20Sopenharmony_ci 3328c2ecf20Sopenharmony_ci pcmd = adap->cmd; 3338c2ecf20Sopenharmony_ci prsp = adap->rsp; 3348c2ecf20Sopenharmony_ci 3358c2ecf20Sopenharmony_ci /* prepare command */ 3368c2ecf20Sopenharmony_ci as10x_cmd_build(pcmd, (++adap->cmd_xid), 3378c2ecf20Sopenharmony_ci sizeof(pcmd->body.get_impulse_rsp.req)); 3388c2ecf20Sopenharmony_ci 3398c2ecf20Sopenharmony_ci /* fill command */ 3408c2ecf20Sopenharmony_ci pcmd->body.get_impulse_rsp.req.proc_id = 3418c2ecf20Sopenharmony_ci cpu_to_le16(CONTROL_PROC_GET_IMPULSE_RESP); 3428c2ecf20Sopenharmony_ci 3438c2ecf20Sopenharmony_ci /* send command */ 3448c2ecf20Sopenharmony_ci if (adap->ops->xfer_cmd) { 3458c2ecf20Sopenharmony_ci error = adap->ops->xfer_cmd(adap, 3468c2ecf20Sopenharmony_ci (uint8_t *) pcmd, 3478c2ecf20Sopenharmony_ci sizeof(pcmd->body.get_impulse_rsp.req) 3488c2ecf20Sopenharmony_ci + HEADER_SIZE, 3498c2ecf20Sopenharmony_ci (uint8_t *) prsp, 3508c2ecf20Sopenharmony_ci sizeof(prsp->body.get_impulse_rsp.rsp) 3518c2ecf20Sopenharmony_ci + HEADER_SIZE); 3528c2ecf20Sopenharmony_ci } 3538c2ecf20Sopenharmony_ci 3548c2ecf20Sopenharmony_ci if (error < 0) 3558c2ecf20Sopenharmony_ci goto out; 3568c2ecf20Sopenharmony_ci 3578c2ecf20Sopenharmony_ci /* parse response */ 3588c2ecf20Sopenharmony_ci error = as10x_rsp_parse(prsp, CONTROL_PROC_GET_IMPULSE_RESP_RSP); 3598c2ecf20Sopenharmony_ci if (error < 0) 3608c2ecf20Sopenharmony_ci goto out; 3618c2ecf20Sopenharmony_ci 3628c2ecf20Sopenharmony_ci /* Response OK -> get response data */ 3638c2ecf20Sopenharmony_ci *is_ready = prsp->body.get_impulse_rsp.rsp.is_ready; 3648c2ecf20Sopenharmony_ci 3658c2ecf20Sopenharmony_ciout: 3668c2ecf20Sopenharmony_ci return error; 3678c2ecf20Sopenharmony_ci} 3688c2ecf20Sopenharmony_ci 3698c2ecf20Sopenharmony_ci/** 3708c2ecf20Sopenharmony_ci * as10x_cmd_build - build AS10x command header 3718c2ecf20Sopenharmony_ci * @pcmd: pointer to AS10x command buffer 3728c2ecf20Sopenharmony_ci * @xid: sequence id of the command 3738c2ecf20Sopenharmony_ci * @cmd_len: length of the command 3748c2ecf20Sopenharmony_ci */ 3758c2ecf20Sopenharmony_civoid as10x_cmd_build(struct as10x_cmd_t *pcmd, 3768c2ecf20Sopenharmony_ci uint16_t xid, uint16_t cmd_len) 3778c2ecf20Sopenharmony_ci{ 3788c2ecf20Sopenharmony_ci pcmd->header.req_id = cpu_to_le16(xid); 3798c2ecf20Sopenharmony_ci pcmd->header.prog = cpu_to_le16(SERVICE_PROG_ID); 3808c2ecf20Sopenharmony_ci pcmd->header.version = cpu_to_le16(SERVICE_PROG_VERSION); 3818c2ecf20Sopenharmony_ci pcmd->header.data_len = cpu_to_le16(cmd_len); 3828c2ecf20Sopenharmony_ci} 3838c2ecf20Sopenharmony_ci 3848c2ecf20Sopenharmony_ci/** 3858c2ecf20Sopenharmony_ci * as10x_rsp_parse - Parse command response 3868c2ecf20Sopenharmony_ci * @prsp: pointer to AS10x command buffer 3878c2ecf20Sopenharmony_ci * @proc_id: id of the command 3888c2ecf20Sopenharmony_ci * 3898c2ecf20Sopenharmony_ci * Return 0 on success or negative value in case of error. 3908c2ecf20Sopenharmony_ci */ 3918c2ecf20Sopenharmony_ciint as10x_rsp_parse(struct as10x_cmd_t *prsp, uint16_t proc_id) 3928c2ecf20Sopenharmony_ci{ 3938c2ecf20Sopenharmony_ci int error; 3948c2ecf20Sopenharmony_ci 3958c2ecf20Sopenharmony_ci /* extract command error code */ 3968c2ecf20Sopenharmony_ci error = prsp->body.common.rsp.error; 3978c2ecf20Sopenharmony_ci 3988c2ecf20Sopenharmony_ci if ((error == 0) && 3998c2ecf20Sopenharmony_ci (le16_to_cpu(prsp->body.common.rsp.proc_id) == proc_id)) { 4008c2ecf20Sopenharmony_ci return 0; 4018c2ecf20Sopenharmony_ci } 4028c2ecf20Sopenharmony_ci 4038c2ecf20Sopenharmony_ci return AS10X_CMD_ERROR; 4048c2ecf20Sopenharmony_ci} 405