/* header file for usb device driver*/
#include "as102_drv.h"
+#include "as10x_cmd.h"
+#include "as102_fe.h"
#include "as102_fw.h"
#include "dvbdev.h"
return 0;
}
+static int as102_set_tune(void *priv, struct as10x_tune_args *tune_args)
+{
+ struct as10x_bus_adapter_t *bus_adap = priv;
+ int ret;
+
+ /* Set frontend arguments */
+ if (mutex_lock_interruptible(&bus_adap->lock))
+ return -EBUSY;
+
+ ret = as10x_cmd_set_tune(bus_adap, tune_args);
+ if (ret != 0)
+ dev_dbg(&bus_adap->usb_dev->dev,
+ "as10x_cmd_set_tune failed. (err = %d)\n", ret);
+
+ mutex_unlock(&bus_adap->lock);
+
+ return ret;
+}
+
+static int as102_get_tps(void *priv, struct as10x_tps *tps)
+{
+ struct as10x_bus_adapter_t *bus_adap = priv;
+ int ret;
+
+ if (mutex_lock_interruptible(&bus_adap->lock))
+ return -EBUSY;
+
+ /* send abilis command: GET_TPS */
+ ret = as10x_cmd_get_tps(bus_adap, tps);
+
+ mutex_unlock(&bus_adap->lock);
+
+ return ret;
+}
+
+static int as102_get_status(void *priv, struct as10x_tune_status *tstate)
+{
+ struct as10x_bus_adapter_t *bus_adap = priv;
+ int ret;
+
+ if (mutex_lock_interruptible(&bus_adap->lock))
+ return -EBUSY;
+
+ /* send abilis command: GET_TUNE_STATUS */
+ ret = as10x_cmd_get_tune_status(bus_adap, tstate);
+ if (ret < 0) {
+ dev_dbg(&bus_adap->usb_dev->dev,
+ "as10x_cmd_get_tune_status failed (err = %d)\n",
+ ret);
+ }
+
+ mutex_unlock(&bus_adap->lock);
+
+ return ret;
+}
+
+static int as102_get_stats(void *priv, struct as10x_demod_stats *demod_stats)
+{
+ struct as10x_bus_adapter_t *bus_adap = priv;
+ int ret;
+
+ if (mutex_lock_interruptible(&bus_adap->lock))
+ return -EBUSY;
+
+ /* send abilis command: GET_TUNE_STATUS */
+ ret = as10x_cmd_get_demod_stats(bus_adap, demod_stats);
+ if (ret < 0) {
+ dev_dbg(&bus_adap->usb_dev->dev,
+ "as10x_cmd_get_demod_stats failed (probably not tuned)\n");
+ } else {
+ dev_dbg(&bus_adap->usb_dev->dev,
+ "demod status: fc: 0x%08x, bad fc: 0x%08x, bytes corrected: 0x%08x , MER: 0x%04x\n",
+ demod_stats->frame_count,
+ demod_stats->bad_frame_count,
+ demod_stats->bytes_fixed_by_rs,
+ demod_stats->mer);
+ }
+ mutex_unlock(&bus_adap->lock);
+
+ return ret;
+}
+
+static int as102_stream_ctrl(void *priv, int acquire, uint32_t elna_cfg)
+{
+ struct as10x_bus_adapter_t *bus_adap = priv;
+ int ret;
+
+ if (mutex_lock_interruptible(&bus_adap->lock))
+ return -EBUSY;
+
+ if (acquire) {
+ if (elna_enable)
+ as10x_cmd_set_context(bus_adap,
+ CONTEXT_LNA, elna_cfg);
+
+ ret = as10x_cmd_turn_on(bus_adap);
+ } else {
+ ret = as10x_cmd_turn_off(bus_adap);
+ }
+
+ mutex_unlock(&bus_adap->lock);
+
+ return ret;
+}
+
+static const struct as102_fe_ops as102_fe_ops = {
+ .set_tune = as102_set_tune,
+ .get_tps = as102_get_tps,
+ .get_status = as102_get_status,
+ .get_stats = as102_get_stats,
+ .stream_ctrl = as102_stream_ctrl,
+};
+
int as102_dvb_register(struct as102_dev_t *as102_dev)
{
struct device *dev = &as102_dev->bus_adap.usb_dev->dev;
/* Attach the frontend */
as102_dev->dvb_fe = dvb_attach(as102_attach, as102_dev->name,
+ &as102_fe_ops,
&as102_dev->bus_adap,
as102_dev->elna_cfg);
if (!as102_dev->dvb_fe) {
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
-#include "as102_drv.h"
-#include "as10x_types.h"
-#include "as10x_cmd.h"
+
+#include <dvb_frontend.h>
+
+#include "as102_fe.h"
struct as102_state {
struct dvb_frontend frontend;
struct as10x_demod_stats demod_stats;
- struct as10x_bus_adapter_t *bus_adap;
+ const struct as102_fe_ops *ops;
+ void *priv;
uint8_t elna_cfg;
/* signal strength */
{
struct as102_state *state = fe->demodulator_priv;
struct dtv_frontend_properties *c = &fe->dtv_property_cache;
- int ret = 0;
struct as10x_tune_args tune_args = { 0 };
/* set frequency */
}
/* Set frontend arguments */
- if (mutex_lock_interruptible(&state->bus_adap->lock))
- return -EBUSY;
-
- ret = as10x_cmd_set_tune(state->bus_adap, &tune_args);
- if (ret != 0)
- dev_dbg(&state->bus_adap->usb_dev->dev,
- "as10x_cmd_set_tune failed. (err = %d)\n", ret);
-
- mutex_unlock(&state->bus_adap->lock);
-
- return (ret < 0) ? -EINVAL : 0;
+ return state->ops->set_tune(state->priv, &tune_args);
}
static int as102_fe_get_frontend(struct dvb_frontend *fe)
int ret = 0;
struct as10x_tps tps = { 0 };
- if (mutex_lock_interruptible(&state->bus_adap->lock))
- return -EBUSY;
-
/* send abilis command: GET_TPS */
- ret = as10x_cmd_get_tps(state->bus_adap, &tps);
-
- mutex_unlock(&state->bus_adap->lock);
-
+ ret = state->ops->get_tps(state->priv, &tps);
if (ret < 0)
return ret;
return 0;
}
-
static int as102_fe_read_status(struct dvb_frontend *fe, fe_status_t *status)
{
int ret = 0;
struct as102_state *state = fe->demodulator_priv;
struct as10x_tune_status tstate = { 0 };
- if (mutex_lock_interruptible(&state->bus_adap->lock))
- return -EBUSY;
-
/* send abilis command: GET_TUNE_STATUS */
- ret = as10x_cmd_get_tune_status(state->bus_adap, &tstate);
- if (ret < 0) {
- dev_dbg(&state->bus_adap->usb_dev->dev,
- "as10x_cmd_get_tune_status failed (err = %d)\n",
- ret);
- goto out;
- }
+ ret = state->ops->get_status(state->priv, &tstate);
+ if (ret < 0)
+ return ret;
state->signal_strength = tstate.signal_strength;
state->ber = tstate.BER;
*status = TUNE_STATUS_NOT_TUNED;
}
- dev_dbg(&state->bus_adap->usb_dev->dev,
- "tuner status: 0x%02x, strength %d, per: %d, ber: %d\n",
- tstate.tune_state, tstate.signal_strength,
- tstate.PER, tstate.BER);
-
- if (*status & FE_HAS_LOCK) {
- if (as10x_cmd_get_demod_stats(state->bus_adap,
- (struct as10x_demod_stats *) &state->demod_stats) < 0) {
- memset(&state->demod_stats, 0, sizeof(state->demod_stats));
- dev_dbg(&state->bus_adap->usb_dev->dev,
- "as10x_cmd_get_demod_stats failed (probably not tuned)\n");
- } else {
- dev_dbg(&state->bus_adap->usb_dev->dev,
- "demod status: fc: 0x%08x, bad fc: 0x%08x, bytes corrected: 0x%08x , MER: 0x%04x\n",
- state->demod_stats.frame_count,
- state->demod_stats.bad_frame_count,
- state->demod_stats.bytes_fixed_by_rs,
- state->demod_stats.mer);
- }
- } else {
+ pr_debug("as102: tuner status: 0x%02x, strength %d, per: %d, ber: %d\n",
+ tstate.tune_state, tstate.signal_strength,
+ tstate.PER, tstate.BER);
+
+ if (!(*status & FE_HAS_LOCK)) {
memset(&state->demod_stats, 0, sizeof(state->demod_stats));
+ return 0;
}
-out:
- mutex_unlock(&state->bus_adap->lock);
+ ret = state->ops->get_stats(state->priv, &state->demod_stats);
+ if (ret < 0)
+ memset(&state->demod_stats, 0, sizeof(state->demod_stats));
+
return ret;
}
static int as102_fe_ts_bus_ctrl(struct dvb_frontend *fe, int acquire)
{
struct as102_state *state = fe->demodulator_priv;
- int ret;
-
- if (mutex_lock_interruptible(&state->bus_adap->lock))
- return -EBUSY;
- if (acquire) {
- if (elna_enable)
- as10x_cmd_set_context(state->bus_adap,
- CONTEXT_LNA, state->elna_cfg);
-
- ret = as10x_cmd_turn_on(state->bus_adap);
- } else {
- ret = as10x_cmd_turn_off(state->bus_adap);
- }
-
- mutex_unlock(&state->bus_adap->lock);
-
- return ret;
+ return state->ops->stream_ctrl(state->priv, acquire,
+ state->elna_cfg);
}
static struct dvb_frontend_ops as102_fe_ops = {
};
struct dvb_frontend *as102_attach(const char *name,
- struct as10x_bus_adapter_t *bus_adap,
+ const struct as102_fe_ops *ops,
+ void *priv,
uint8_t elna_cfg)
{
struct as102_state *state;
state = kzalloc(sizeof(struct as102_state), GFP_KERNEL);
if (state == NULL) {
- dev_err(&bus_adap->usb_dev->dev,
- "%s: unable to allocate memory for state\n", __func__);
+ pr_err("%s: unable to allocate memory for state\n", __func__);
return NULL;
}
fe = &state->frontend;
fe->demodulator_priv = state;
- state->bus_adap = bus_adap;
+ state->ops = ops;
+ state->priv = priv;
state->elna_cfg = elna_cfg;
/* init frontend callback ops */
--- /dev/null
+/*
+ * Abilis Systems Single DVB-T Receiver
+ * Copyright (C) 2014 Mauro Carvalho Chehab <m.chehab@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include "as10x_types.h"
+
+struct as102_fe_ops {
+ int (*set_tune)(void *priv, struct as10x_tune_args *tune_args);
+ int (*get_tps)(void *priv, struct as10x_tps *tps);
+ int (*get_status)(void *priv, struct as10x_tune_status *tstate);
+ int (*get_stats)(void *priv, struct as10x_demod_stats *demod_stats);
+ int (*stream_ctrl)(void *priv, int acquire, uint32_t elna_cfg);
+};
+
+struct dvb_frontend *as102_attach(const char *name,
+ const struct as102_fe_ops *ops,
+ void *priv,
+ uint8_t elna_cfg);