Johannes Stezenbach wrote: > On Fri, Nov 02, 2007, Steven Toth wrote: >> The design goals for me are: >> >> 1) We stop trying to predict what the API will need in 5 years, and focus >> on building a very simplistic ioctl API for getting and setting generic >> frontend properties, it should be basic enough to deal with any new >> modulation type (or advanced tuner) that we know of today. > > good one > >> 2) We change the tuning mechanism from being (mostly) atomic (SET_FRONTEND) >> to a looser command/sequence definition. (Thereby stepping away from fixed >> structs that define the ABI). With two new ioctls >> (get_property/set_property) and a simple property struct which specifies >> how generic types are passed to/from the kernel. > > no so good > >> 3) A userland library _may_ offer a number of helper functions to simplify >> in terms of applications development, turning this: > > many people seem to hate ALSA, there's a lesson to be learned here > >> command.id = BEGIN_TRANSACTION >> ioctl(SET_PROPERTY, &command); >> >> command.id = SET_MODULATION >> command.arg = 8VSB >> ioctl(SET_PROPERTY, &command); >> >> command.id = SET_FREQUENCY >> command.arg = 591250000 >> ioctl(SET_PROPERTY, &command); >> >> command.id = VALIDATE_TRANSACTION >> ioctl(SET_PROPERTY, &command); >> >> command.id = END_TRANSACTION >> ioctl(SET_PROPERTY, &command); >> >> Into a more human readable form like this: >> >> int tune_8vsb(frequency); >> >> It's a basic approach, we trade off multiple ioctls (at a very low rate) >> entering the kernel, for a very flexible tuning approach to frontend >> control. > > Once you have those tag/value pairs, you could batch them > together in an array and pass them down in one ioctl. This > avoids the ugly transaction stuff and keeps it atomic. > And I think it wouldn't look too ugly in user code, e.g.: > > struct dvb_tuning_param p[3] = { > { .id = MODULATION, .val = MOD_8VSB }, > { .id = FREQUENCY, .val = 591250000 }, > { .id = 0 } > }; > ioctl(fd, DVB_TUNE, p); You can't reliably pass in variably length arrays into the kernel, or none of the other kernel wide drivers do, they need to be fixed length for sanity reasons. That being said, I have a newly defined type which represents an array enabling 16 messages to be passed in a single transaction. IE. It's no limited by array size. ioctls can be chained together to form atomic tuning operations and are not bound by length, should any future hardware require radically different parameters/operations. Here's the message set I've using with QAM for example: tv_properties_t _qam_cmdseq = { { .cmd = TV_SEQ_START }, { .cmd = TV_SET_FREQUENCY, .u.data = 561000000 }, { .cmd = TV_SET_MODULATION, .u.data = QAM_AUTO }, { .cmd = TV_SET_INVERSION, .u.data = INVERSION_AUTO }, { .cmd = TV_SET_BANDWIDTH, .u.data = BANDWIDTH_AUTO }, { .cmd = TV_SEQ_COMPLETE }, { .cmd = 0 }, }; ... and here's the ioctl structure in question from frontend.h typedef struct { __u32 cmd; union { __u32 data; struct { __u8 data[32]; __u32 len; } buffer; } u; } tv_property_t; /* No more than 16 properties during any given ioctl */ typedef tv_property_t tv_properties_t[16]; #define FE_SET_PROPERTY _IOW('o', 82, tv_properties_t) I have other changes to frontend.h that I'll describe below, in answer to your other points. Unrelated: It's important to note that the new API allows messages to be atomic individually, or grouped into transactions for a single atomic operation. One example is a single message to control DiSEqC, which in the current published API occurs immediately. The current API is completely atomic, and offers nothing for future hardware which may need a finer grain of control. (Think analog) Hence, this API supports both mechanisms. > > > But there's more work to do: > - need for .val being variable lenght or a union of different types? See the current union. It supports a generic u32 for passing enums or other values, and also a generic byte buffer (which can be chained with multiple messages and multiple ioctls via transactions grouping). This generic buffer is large enough to store the current DiSEqC message mechanisms, but scalable to be able to support any number of future messages with any message lengths, literally into multi megabytes if that's what is required. > - extend existing enums or define new ones for MODULATION etc? A mixture of both. Where appropriate the current enums have been extended to support new modulation types, FECs etc. In more cases than not, this is the case. Where appropriate new enums/type have been defined to support new user facing attributes (rolloff/pilot) being a classic case (although both current drivers detect Pilot automatically). This doesn't impact the ABI, but mechanisms like this (for future devices) show how flexible the new API can be. The ioctls messages themselves (TV_SET_FREQUENCY etc) are also new enums, but the impact is small to frontend.h and retains full backwards compatibility for existing users. No ABI changes. > - how to do FE_GET_FRONTEND Interesting. I haven't looked into this mainly because my focus this weekend (on short notice) was to prove out basic tuning. Assuming the direction that's being taken so far is sound, then I'll look into this next. With the new patches I have, QAM and ATSC are working cleanly and 100% reliably. These patches allow the old or new API to be used to tune and to query some basic tuner metrics (locked/sync etc). Importantly, because the new API works independently of the current API, it can be used in combination as a stepping stone for applications that do not want to migrate overnight. That's an unwritten goal. Here's the basic tuning mechanism, in snippet form: tv_properties_t _qam_cmdseq = { { .cmd = TV_SEQ_START }, { .cmd = TV_SET_FREQUENCY, .u.data = 561000000 }, { .cmd = TV_SET_MODULATION, .u.data = QAM_AUTO }, { .cmd = TV_SET_INVERSION, .u.data = INVERSION_AUTO }, { .cmd = TV_SET_BANDWIDTH, .u.data = BANDWIDTH_AUTO }, { .cmd = TV_SEQ_COMPLETE }, { .cmd = 0 }, }; ioctl(fefd, FE_SET_PROPERTY, &_qam_cmdseq)); As such FE_GET_FRONTEND continues to work 100% reliably for existing drivers, but I would also expect to have a TV_GET_FRONTEND style message to return a superset of data in a cleaner non-fixed-structured way. > - etc. > > I'm sure we could have endless debates over the details ;-) > > I hope many others will comment which approach they like better, > or which one they think will be ready for prime time sooner. All feedback is appreciated. > > Personally I don't care either way. I spent a lot of time discussing > the "multiproto" API and I believe it could be ready soon with > a few minor tweaks. OTOH this tag/value approach seems to be > more flexible, but who knows how much work it'll take to complete. Clearly, tuning for 8PSK would look something like this: tv_properties_t _8psk_cmdseq = { { .cmd = TV_SEQ_START }, { .cmd = TV_SET_FREQUENCY, .u.data = 12051000 }, { .cmd = TV_SET_MODULATION, .u.data = _8PSK }, { .cmd = TV_SET_SYMBOLRATE, .u.data = 27500 }, { .cmd = TV_SET_INNERFEC, .u.data = FEC_AUTO }, { .cmd = TV_SET_VOLTAGE, .u.data = SEC_VOLTAGE_13 }, { .cmd = TV_SET_INVERSION, .u.data = INVERSION_AUTO }, { .cmd = TV_SET_PILOT, .u.data = PILOT_AUTO }, { .cmd = TV_SET_ROLLOFF, .u.data = ROLLOFF_AUTO }, { .cmd = TV_SEQ_COMPLETE }, { .cmd = 0 }, }; ioctl(fefd, FE_SET_PROPERTY, &_qam_cmdseq)); -- with some of these messages being optional, I have them here for reading purposes. Lastly, a few things I want to mention. 1) I've made minor changes to dvb_core to interpret these messages and handle the ioctl. No changes have been made to the frontend drivers. 2) Adding support for s2 _inside_ the kernel will mean adding a single method to dvb_frontend_ops which allows the dvb_core to notify a new S2 driver. The goal here is to minimize these changes also. I haven't demonstrated that code here, becuse I felt it was more important to show the impact to the userland API/ABI, knowing that DVB-S2 and other advanced types (including analog) would naturally fit well within this model. 3) This applies to all devs. I welcome all feedback, for sure the sytax might need some cleanup, but please don't shoot the idea down when it's only had 6-8 hours work of engineering behind it. It's proof of concept. It doesn't contain any of Manu's code so I don't feel bound politically or technically. I think given another 4-5 hours I could show the HVR4000 working, and demonstrate many of the userland signal/statistic API's. At this stage I'm looking for a "Yes, in principle we like the idea, but show me how you do feature XYZ" from other devs. At which point I'll flush out more code this would probably lead to an RFC for your approval. - Steve _______________________________________________ linux-dvb mailing list linux-dvb@xxxxxxxxxxx http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb