Pierrick Hascoet | 315cadc | 2011-10-31 12:24:49 -0300 | [diff] [blame] | 1 | /* |
| 2 | * Abilis Systems Single DVB-T Receiver |
| 3 | * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com> |
| 4 | * |
| 5 | * This program is free software; you can redistribute it and/or modify |
| 6 | * it under the terms of the GNU General Public License as published by |
| 7 | * the Free Software Foundation; either version 2, or (at your option) |
| 8 | * any later version. |
| 9 | * |
| 10 | * This program is distributed in the hope that it will be useful, |
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 13 | * GNU General Public License for more details. |
| 14 | * |
| 15 | * You should have received a copy of the GNU General Public License |
| 16 | * along with this program; if not, write to the Free Software |
| 17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| 18 | */ |
Pierrick Hascoet | 41b44e0 | 2011-10-31 12:24:39 -0300 | [diff] [blame] | 19 | |
Pierrick Hascoet | 41b44e0 | 2011-10-31 12:24:39 -0300 | [diff] [blame] | 20 | #include <linux/kernel.h> |
| 21 | #include "as102_drv.h" |
Pierrick Hascoet | 41b44e0 | 2011-10-31 12:24:39 -0300 | [diff] [blame] | 22 | #include "as10x_types.h" |
| 23 | #include "as10x_cmd.h" |
| 24 | |
| 25 | /***************************/ |
| 26 | /* FUNCTION DEFINITION */ |
| 27 | /***************************/ |
| 28 | |
| 29 | /** |
Sylwester Nawrocki | 3b4544a | 2011-10-31 12:24:51 -0300 | [diff] [blame] | 30 | * as10x_cmd_get_context - Send get context command to AS10x |
Sylwester Nawrocki | 34490a0 | 2011-11-06 16:31:50 -0300 | [diff] [blame] | 31 | * @adap: pointer to AS10x bus adapter |
Sylwester Nawrocki | 3b4544a | 2011-10-31 12:24:51 -0300 | [diff] [blame] | 32 | * @tag: context tag |
| 33 | * @pvalue: pointer where to store context value read |
| 34 | * |
| 35 | * Return 0 on success or negative value in case of error. |
| 36 | */ |
Sylwester Nawrocki | 34490a0 | 2011-11-06 16:31:50 -0300 | [diff] [blame] | 37 | int as10x_cmd_get_context(struct as10x_bus_adapter_t *adap, uint16_t tag, |
Pierrick Hascoet | 41b44e0 | 2011-10-31 12:24:39 -0300 | [diff] [blame] | 38 | uint32_t *pvalue) |
| 39 | { |
Devin Heitmueller | e2e02ca | 2011-10-31 12:24:46 -0300 | [diff] [blame] | 40 | int error; |
| 41 | struct as10x_cmd_t *pcmd, *prsp; |
Pierrick Hascoet | 41b44e0 | 2011-10-31 12:24:39 -0300 | [diff] [blame] | 42 | |
Devin Heitmueller | e2e02ca | 2011-10-31 12:24:46 -0300 | [diff] [blame] | 43 | ENTER(); |
Pierrick Hascoet | 41b44e0 | 2011-10-31 12:24:39 -0300 | [diff] [blame] | 44 | |
Sylwester Nawrocki | 34490a0 | 2011-11-06 16:31:50 -0300 | [diff] [blame] | 45 | pcmd = adap->cmd; |
| 46 | prsp = adap->rsp; |
Pierrick Hascoet | 41b44e0 | 2011-10-31 12:24:39 -0300 | [diff] [blame] | 47 | |
Devin Heitmueller | e2e02ca | 2011-10-31 12:24:46 -0300 | [diff] [blame] | 48 | /* prepare command */ |
Sylwester Nawrocki | 34490a0 | 2011-11-06 16:31:50 -0300 | [diff] [blame] | 49 | as10x_cmd_build(pcmd, (++adap->cmd_xid), |
Devin Heitmueller | e2e02ca | 2011-10-31 12:24:46 -0300 | [diff] [blame] | 50 | sizeof(pcmd->body.context.req)); |
Pierrick Hascoet | 41b44e0 | 2011-10-31 12:24:39 -0300 | [diff] [blame] | 51 | |
Devin Heitmueller | e2e02ca | 2011-10-31 12:24:46 -0300 | [diff] [blame] | 52 | /* fill command */ |
| 53 | pcmd->body.context.req.proc_id = cpu_to_le16(CONTROL_PROC_CONTEXT); |
| 54 | pcmd->body.context.req.tag = cpu_to_le16(tag); |
| 55 | pcmd->body.context.req.type = cpu_to_le16(GET_CONTEXT_DATA); |
Pierrick Hascoet | 41b44e0 | 2011-10-31 12:24:39 -0300 | [diff] [blame] | 56 | |
Devin Heitmueller | e2e02ca | 2011-10-31 12:24:46 -0300 | [diff] [blame] | 57 | /* send command */ |
Sylwester Nawrocki | 34490a0 | 2011-11-06 16:31:50 -0300 | [diff] [blame] | 58 | if (adap->ops->xfer_cmd) { |
| 59 | error = adap->ops->xfer_cmd(adap, |
| 60 | (uint8_t *) pcmd, |
| 61 | sizeof(pcmd->body.context.req) |
| 62 | + HEADER_SIZE, |
| 63 | (uint8_t *) prsp, |
| 64 | sizeof(prsp->body.context.rsp) |
| 65 | + HEADER_SIZE); |
Devin Heitmueller | e2e02ca | 2011-10-31 12:24:46 -0300 | [diff] [blame] | 66 | } else { |
| 67 | error = AS10X_CMD_ERROR; |
| 68 | } |
Pierrick Hascoet | 41b44e0 | 2011-10-31 12:24:39 -0300 | [diff] [blame] | 69 | |
Devin Heitmueller | e2e02ca | 2011-10-31 12:24:46 -0300 | [diff] [blame] | 70 | if (error < 0) |
| 71 | goto out; |
Pierrick Hascoet | 41b44e0 | 2011-10-31 12:24:39 -0300 | [diff] [blame] | 72 | |
Devin Heitmueller | e2e02ca | 2011-10-31 12:24:46 -0300 | [diff] [blame] | 73 | /* parse response: context command do not follow the common response */ |
| 74 | /* structure -> specific handling response parse required */ |
| 75 | error = as10x_context_rsp_parse(prsp, CONTROL_PROC_CONTEXT_RSP); |
Pierrick Hascoet | 41b44e0 | 2011-10-31 12:24:39 -0300 | [diff] [blame] | 76 | |
Devin Heitmueller | e2e02ca | 2011-10-31 12:24:46 -0300 | [diff] [blame] | 77 | if (error == 0) { |
| 78 | /* Response OK -> get response data */ |
| 79 | *pvalue = le32_to_cpu(prsp->body.context.rsp.reg_val.u.value32); |
| 80 | /* value returned is always a 32-bit value */ |
| 81 | } |
Pierrick Hascoet | 41b44e0 | 2011-10-31 12:24:39 -0300 | [diff] [blame] | 82 | |
| 83 | out: |
Devin Heitmueller | e2e02ca | 2011-10-31 12:24:46 -0300 | [diff] [blame] | 84 | LEAVE(); |
| 85 | return error; |
Pierrick Hascoet | 41b44e0 | 2011-10-31 12:24:39 -0300 | [diff] [blame] | 86 | } |
| 87 | |
| 88 | /** |
Sylwester Nawrocki | 3b4544a | 2011-10-31 12:24:51 -0300 | [diff] [blame] | 89 | * as10x_cmd_set_context - send set context command to AS10x |
Sylwester Nawrocki | 34490a0 | 2011-11-06 16:31:50 -0300 | [diff] [blame] | 90 | * @adap: pointer to AS10x bus adapter |
Sylwester Nawrocki | 3b4544a | 2011-10-31 12:24:51 -0300 | [diff] [blame] | 91 | * @tag: context tag |
| 92 | * @value: value to set in context |
| 93 | * |
| 94 | * Return 0 on success or negative value in case of error. |
| 95 | */ |
Sylwester Nawrocki | 34490a0 | 2011-11-06 16:31:50 -0300 | [diff] [blame] | 96 | int as10x_cmd_set_context(struct as10x_bus_adapter_t *adap, uint16_t tag, |
Pierrick Hascoet | 41b44e0 | 2011-10-31 12:24:39 -0300 | [diff] [blame] | 97 | uint32_t value) |
| 98 | { |
Devin Heitmueller | e2e02ca | 2011-10-31 12:24:46 -0300 | [diff] [blame] | 99 | int error; |
| 100 | struct as10x_cmd_t *pcmd, *prsp; |
Pierrick Hascoet | 41b44e0 | 2011-10-31 12:24:39 -0300 | [diff] [blame] | 101 | |
Devin Heitmueller | e2e02ca | 2011-10-31 12:24:46 -0300 | [diff] [blame] | 102 | ENTER(); |
Pierrick Hascoet | 41b44e0 | 2011-10-31 12:24:39 -0300 | [diff] [blame] | 103 | |
Sylwester Nawrocki | 34490a0 | 2011-11-06 16:31:50 -0300 | [diff] [blame] | 104 | pcmd = adap->cmd; |
| 105 | prsp = adap->rsp; |
Pierrick Hascoet | 41b44e0 | 2011-10-31 12:24:39 -0300 | [diff] [blame] | 106 | |
Devin Heitmueller | e2e02ca | 2011-10-31 12:24:46 -0300 | [diff] [blame] | 107 | /* prepare command */ |
Sylwester Nawrocki | 34490a0 | 2011-11-06 16:31:50 -0300 | [diff] [blame] | 108 | as10x_cmd_build(pcmd, (++adap->cmd_xid), |
Devin Heitmueller | e2e02ca | 2011-10-31 12:24:46 -0300 | [diff] [blame] | 109 | sizeof(pcmd->body.context.req)); |
Pierrick Hascoet | 41b44e0 | 2011-10-31 12:24:39 -0300 | [diff] [blame] | 110 | |
Devin Heitmueller | e2e02ca | 2011-10-31 12:24:46 -0300 | [diff] [blame] | 111 | /* fill command */ |
| 112 | pcmd->body.context.req.proc_id = cpu_to_le16(CONTROL_PROC_CONTEXT); |
| 113 | /* pcmd->body.context.req.reg_val.mode initialization is not required */ |
| 114 | pcmd->body.context.req.reg_val.u.value32 = cpu_to_le32(value); |
| 115 | pcmd->body.context.req.tag = cpu_to_le16(tag); |
| 116 | pcmd->body.context.req.type = cpu_to_le16(SET_CONTEXT_DATA); |
Pierrick Hascoet | 41b44e0 | 2011-10-31 12:24:39 -0300 | [diff] [blame] | 117 | |
Devin Heitmueller | e2e02ca | 2011-10-31 12:24:46 -0300 | [diff] [blame] | 118 | /* send command */ |
Sylwester Nawrocki | 34490a0 | 2011-11-06 16:31:50 -0300 | [diff] [blame] | 119 | if (adap->ops->xfer_cmd) { |
| 120 | error = adap->ops->xfer_cmd(adap, |
| 121 | (uint8_t *) pcmd, |
| 122 | sizeof(pcmd->body.context.req) |
| 123 | + HEADER_SIZE, |
| 124 | (uint8_t *) prsp, |
| 125 | sizeof(prsp->body.context.rsp) |
| 126 | + HEADER_SIZE); |
Devin Heitmueller | e2e02ca | 2011-10-31 12:24:46 -0300 | [diff] [blame] | 127 | } else { |
| 128 | error = AS10X_CMD_ERROR; |
| 129 | } |
Pierrick Hascoet | 41b44e0 | 2011-10-31 12:24:39 -0300 | [diff] [blame] | 130 | |
Devin Heitmueller | e2e02ca | 2011-10-31 12:24:46 -0300 | [diff] [blame] | 131 | if (error < 0) |
| 132 | goto out; |
Pierrick Hascoet | 41b44e0 | 2011-10-31 12:24:39 -0300 | [diff] [blame] | 133 | |
Devin Heitmueller | e2e02ca | 2011-10-31 12:24:46 -0300 | [diff] [blame] | 134 | /* parse response: context command do not follow the common response */ |
| 135 | /* structure -> specific handling response parse required */ |
| 136 | error = as10x_context_rsp_parse(prsp, CONTROL_PROC_CONTEXT_RSP); |
Pierrick Hascoet | 41b44e0 | 2011-10-31 12:24:39 -0300 | [diff] [blame] | 137 | |
| 138 | out: |
Devin Heitmueller | e2e02ca | 2011-10-31 12:24:46 -0300 | [diff] [blame] | 139 | LEAVE(); |
| 140 | return error; |
Pierrick Hascoet | 41b44e0 | 2011-10-31 12:24:39 -0300 | [diff] [blame] | 141 | } |
| 142 | |
| 143 | /** |
Sylwester Nawrocki | 3b4544a | 2011-10-31 12:24:51 -0300 | [diff] [blame] | 144 | * as10x_cmd_eLNA_change_mode - send eLNA change mode command to AS10x |
Sylwester Nawrocki | 34490a0 | 2011-11-06 16:31:50 -0300 | [diff] [blame] | 145 | * @adap: pointer to AS10x bus adapter |
Sylwester Nawrocki | 3b4544a | 2011-10-31 12:24:51 -0300 | [diff] [blame] | 146 | * @mode: mode selected: |
| 147 | * - ON : 0x0 => eLNA always ON |
| 148 | * - OFF : 0x1 => eLNA always OFF |
| 149 | * - AUTO : 0x2 => eLNA follow hysteresis parameters |
| 150 | * to be ON or OFF |
| 151 | * |
| 152 | * Return 0 on success or negative value in case of error. |
| 153 | */ |
Sylwester Nawrocki | 34490a0 | 2011-11-06 16:31:50 -0300 | [diff] [blame] | 154 | int as10x_cmd_eLNA_change_mode(struct as10x_bus_adapter_t *adap, uint8_t mode) |
Pierrick Hascoet | 41b44e0 | 2011-10-31 12:24:39 -0300 | [diff] [blame] | 155 | { |
Devin Heitmueller | e2e02ca | 2011-10-31 12:24:46 -0300 | [diff] [blame] | 156 | int error; |
| 157 | struct as10x_cmd_t *pcmd, *prsp; |
Pierrick Hascoet | 41b44e0 | 2011-10-31 12:24:39 -0300 | [diff] [blame] | 158 | |
Devin Heitmueller | e2e02ca | 2011-10-31 12:24:46 -0300 | [diff] [blame] | 159 | ENTER(); |
Pierrick Hascoet | 41b44e0 | 2011-10-31 12:24:39 -0300 | [diff] [blame] | 160 | |
Sylwester Nawrocki | 34490a0 | 2011-11-06 16:31:50 -0300 | [diff] [blame] | 161 | pcmd = adap->cmd; |
| 162 | prsp = adap->rsp; |
Pierrick Hascoet | 41b44e0 | 2011-10-31 12:24:39 -0300 | [diff] [blame] | 163 | |
Devin Heitmueller | e2e02ca | 2011-10-31 12:24:46 -0300 | [diff] [blame] | 164 | /* prepare command */ |
Sylwester Nawrocki | 34490a0 | 2011-11-06 16:31:50 -0300 | [diff] [blame] | 165 | as10x_cmd_build(pcmd, (++adap->cmd_xid), |
Devin Heitmueller | e2e02ca | 2011-10-31 12:24:46 -0300 | [diff] [blame] | 166 | sizeof(pcmd->body.cfg_change_mode.req)); |
Pierrick Hascoet | 41b44e0 | 2011-10-31 12:24:39 -0300 | [diff] [blame] | 167 | |
Devin Heitmueller | e2e02ca | 2011-10-31 12:24:46 -0300 | [diff] [blame] | 168 | /* fill command */ |
| 169 | pcmd->body.cfg_change_mode.req.proc_id = |
| 170 | cpu_to_le16(CONTROL_PROC_ELNA_CHANGE_MODE); |
| 171 | pcmd->body.cfg_change_mode.req.mode = mode; |
Pierrick Hascoet | 41b44e0 | 2011-10-31 12:24:39 -0300 | [diff] [blame] | 172 | |
Devin Heitmueller | e2e02ca | 2011-10-31 12:24:46 -0300 | [diff] [blame] | 173 | /* send command */ |
Sylwester Nawrocki | 34490a0 | 2011-11-06 16:31:50 -0300 | [diff] [blame] | 174 | if (adap->ops->xfer_cmd) { |
| 175 | error = adap->ops->xfer_cmd(adap, (uint8_t *) pcmd, |
Devin Heitmueller | e2e02ca | 2011-10-31 12:24:46 -0300 | [diff] [blame] | 176 | sizeof(pcmd->body.cfg_change_mode.req) |
| 177 | + HEADER_SIZE, (uint8_t *) prsp, |
| 178 | sizeof(prsp->body.cfg_change_mode.rsp) |
| 179 | + HEADER_SIZE); |
| 180 | } else { |
| 181 | error = AS10X_CMD_ERROR; |
| 182 | } |
Pierrick Hascoet | 41b44e0 | 2011-10-31 12:24:39 -0300 | [diff] [blame] | 183 | |
Devin Heitmueller | e2e02ca | 2011-10-31 12:24:46 -0300 | [diff] [blame] | 184 | if (error < 0) |
| 185 | goto out; |
Pierrick Hascoet | 41b44e0 | 2011-10-31 12:24:39 -0300 | [diff] [blame] | 186 | |
Devin Heitmueller | e2e02ca | 2011-10-31 12:24:46 -0300 | [diff] [blame] | 187 | /* parse response */ |
| 188 | error = as10x_rsp_parse(prsp, CONTROL_PROC_ELNA_CHANGE_MODE_RSP); |
Pierrick Hascoet | 41b44e0 | 2011-10-31 12:24:39 -0300 | [diff] [blame] | 189 | |
| 190 | out: |
Devin Heitmueller | e2e02ca | 2011-10-31 12:24:46 -0300 | [diff] [blame] | 191 | LEAVE(); |
| 192 | return error; |
Pierrick Hascoet | 41b44e0 | 2011-10-31 12:24:39 -0300 | [diff] [blame] | 193 | } |
| 194 | |
| 195 | /** |
Sylwester Nawrocki | 3b4544a | 2011-10-31 12:24:51 -0300 | [diff] [blame] | 196 | * as10x_context_rsp_parse - Parse context command response |
| 197 | * @prsp: pointer to AS10x command response buffer |
| 198 | * @proc_id: id of the command |
| 199 | * |
Masanari Iida | 6dc8f38 | 2012-10-31 11:52:45 -0300 | [diff] [blame] | 200 | * Since the contex command response does not follow the common |
Sylwester Nawrocki | 3b4544a | 2011-10-31 12:24:51 -0300 | [diff] [blame] | 201 | * response, a specific parse function is required. |
| 202 | * Return 0 on success or negative value in case of error. |
| 203 | */ |
Devin Heitmueller | e2e02ca | 2011-10-31 12:24:46 -0300 | [diff] [blame] | 204 | int as10x_context_rsp_parse(struct as10x_cmd_t *prsp, uint16_t proc_id) |
| 205 | { |
| 206 | int err; |
Pierrick Hascoet | 41b44e0 | 2011-10-31 12:24:39 -0300 | [diff] [blame] | 207 | |
Devin Heitmueller | e2e02ca | 2011-10-31 12:24:46 -0300 | [diff] [blame] | 208 | err = prsp->body.context.rsp.error; |
Pierrick Hascoet | 41b44e0 | 2011-10-31 12:24:39 -0300 | [diff] [blame] | 209 | |
Devin Heitmueller | e2e02ca | 2011-10-31 12:24:46 -0300 | [diff] [blame] | 210 | if ((err == 0) && |
| 211 | (le16_to_cpu(prsp->body.context.rsp.proc_id) == proc_id)) { |
| 212 | return 0; |
| 213 | } |
| 214 | return AS10X_CMD_ERROR; |
Pierrick Hascoet | 41b44e0 | 2011-10-31 12:24:39 -0300 | [diff] [blame] | 215 | } |